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.

おすすめ記事