bashを使用してバイナリファイルの単一バイトを変数として抽出します。

bashを使用してバイナリファイルの単一バイトを変数として抽出します。

バイナリファイルから一度に1バイトずつ抽出してシリアルポートに送信し、次のバイトを送信する前に1バイトが戻るまで待つ非常に単純なbashスクリプトを作成する必要があります。既製のソリューションは機能しないため、これはEEPROMプログラマに適しています。

私は主にファイルから変数にバイトを抽出する作業をしています。それ以外は、値をシリアルポートにエコーし、ddを使用して再読み込みできることを知っています。 (もっと良い方法はありますか?)

助けてくれてありがとう!

答え1

たとえば、バイナリファイルからオフセット100()のバイトを読み取るには、ddor(Vimの一部)を使用して次のようにします。xxd-l-s

xxd -p -l1 -s 100 file.bin

16進オフセットを使用するには、Bashで次の構文を使用できます$((16#64))。例:

echo $((16#$(xxd -p -l1 -s $((16#FC)) file.bin)))

オフセットからバイトを読み取り、FCそれを10進形式で印刷します。

またはを使用してくださいdd。たとえば、次のようになります。

dd if=file.bin seek=$((16#FC)) bs=1 count=5 status=none

16進オフセットに5バイトの生データをダンプしますFC

その後、変数に割り当てることができますが、データに NULL バイトがある場合は動作しません。なのでスキップできます( xxd -a)。あるいは、回避策として通常の16進形式で保存することもできます。

たとえば、

  1. 16進形式のバイトを含む変数で、オフセット10の10バイトを読み取ります。

    hex=$(xxd -p -l 10 -s 10 file.bin)
    
  2. その後、ファイルまたはデバイスに書き込みます。

    xxd -r -p > out.bin <<<$hex
    

Bashの便利な機能は次のとおりです。

set -e

# Read single decimal value at given offset from the file.
read_value() {
  file="$1"
  offset="$2"
  [ -n "$file" ]
  [ -n "$offset" ]
  echo $((16#$(xxd -p -l1 -s $offset "$file")))
}

# Read bytes in hex format at given offset from the file.
read_data() {
  file="$1"
  offset="$2"
  count="$3:-1"
  xxd -p -l $count -s $offset "$file"
}

使用例:

read_value file.bin $((16#FC)) # Read 0xFC offset from file.bin.

答え2

あなたが求めるものの全体像を私がよく理解しているかどうかはわかりません。しかし、考慮すべきいくつかのアプローチがあります。

dd入力ファイルを読むには

実行3<入力ファイル
本当ではありますが
する
    dd bs=1 count=1 <&3 > this_byte
    もし! [ -s this_byte ] # サイズが0の場合、操作は完了です。
    それから
        残り
    フィリピン諸島
    コードの使い方このバイト文書
完璧

od入力ファイルを消化する

OD-BV入力ファイル| a0 a1 a2 a3 a4 a5 a6 a7 a8 a9 a10 a11 a12 a13 a14 a15 a16 同時に読む
do#スキップ$a0;これが住所です。
    "$a1" "$a2" "$a3" "$a4" "$a5" "$a6" "$a7" "$a8" "$a9" "$a10" \ の byte_val の場合
                                “$a11” “$a12” “$a13” “$a14” “$a15” “$a16”
    する
        if["$byte_val" = ""]]
        それから
            残り
        フィリピン諸島
        コードの使い方$byte_val
        たとえば、echo -e "\0$byte_val\c"
    完璧
完璧

答え3

小さなCプログラムや(ほぼ)PythonやPerlなどのスクリプト言語の1行のコードを使用してこれを行うのは簡単かもしれません。

Unixシェルはユーザーコマンド通訳には基本的なプログラミング機能があります(繰り返しコマンドを簡単に作成できるように)。 Bourne シェルのバージョンは次のようになるため、しばしば(誤って)使用されます。保証するこれは特に良い(または半分くらいの)プログラミング言語であるためではなく、すべてのUnixシステムで使用できます。

答え4

あなたはそれを使用することができますperl

$ printf '%s%s%s' 'ăâé' | LC_ALL=C.UTF-8 perl -Mopen=locale -ne '
    BEGIN { $/ = \1 }
    printf "%s\n", $_;
'
ă
â
é

関連情報