BashでASCII値の代わりにバイナリ値をファイルに書き込む方法

BashでASCII値の代わりにバイナリ値をファイルに書き込む方法

私は、ファイル記述子を介してアクセスできるいくつかのメモリを含む組み込みシステムで作業しています。 (何を言っているのかわかりません。間違っている場合は訂正してください。)

メモリは32kBで、0x00から0xFFFFFFFFまで埋めたいです。テキストファイルが次のようになることがわかります。

exec {fh} >> ./eeprom;
for i in {0..32767}; do echo $i >& $fh; done; $fh>&-;

これにより、ASCII文字0〜977が記録されます。

これにより、次のようなhexdump eeprop | head結果が得られます。

0000000 0a30 0a31 0a32 0a33 0a34 0a35 0a36 0a37
0000010 0a38 0a39 3031 310a 0a31 3231 310a 0a33
0000020 3431 310a 0a35 3631 310a 0a37 3831 310a
0000030 0a39 3032 320a 0a31 3232 320a 0a33 3432
0000040 320a 0a35 3632 320a 0a37 3832 320a 0a39
0000050 3033 330a 0a31 3233 330a 0a33 3433 330a
0000060 0a35 3633 330a 0a37 3833 330a 0a39 3034
0000070 340a 0a31 3234 340a 0a33 3434 340a 0a35
0000080 3634 340a 0a37 3834 340a 0a39 3035 350a
0000090 0a31 3235 350a 0a33 3435 350a 0a35 3635

uint32各アドレスをASCII表現ではなくアドレスで埋めるにはどうすればよいですか?

ベストアンサー1

perl -e 'print pack "L*", 0..0x7fff' > file

ローカルシステムのバイト順で記録されます。

使用:

perl -e 'print pack "L>*", 0..0x7fff'
perl -e 'print pack "L<*", 0..0x7fff'

ローカルシステムの基本バイト順序に関係なく、それぞれビッグエンディアンまたはリトルエンディアンを強制します。

perldoc -f pack詳細より。

具体的には、bashの組み込み機能を使用すると、必要なものを書くことができます。バイト値は次のとおりです。

printf '\123' # 123 in octal
printf '\xff' # ff in hexadecimal

したがって、次のようにuint32数値の各バイトを手動で作成するだけです。

for ((i = 0; i <= 32767; i++)); do
  printf -v format '\\x%x' \
    "$((         i & 0xff ))" \
    "$(( (i >>  8) & 0xff ))" \
    "$(( (i >> 16) & 0xff ))" \
    "$(( (i >> 24) & 0xff ))"
  printf "$format"
done

(ここではリトルエンディアン)。

とにかく32767は0x7fffではないことに注意してください。0xFFFFFFFF。 uint32数字0〜32767は32kbではなく128KiBを占めます。 0~0xFFFFFFFFは16GiBを占めます。

これらの16GiBを書くには、perlコードを次のように変更する必要があります。

perl -e 'print pack "L", $_ for 0..0xffffffff'

そうしないと、対応する16GiBをメモリに割り当てようとし、失敗する可能性があります。私のシステムでは、perl書き込み出力は約30MiB / sでbash書き込みは約250KiB / sです(したがって完了するまでに数時間かかります)。

32kb(32000ビット、4000バイト、1000 uint32数値)uint32数値を書き込むには、0..999の範囲を使用できます。 32KiBは0..8191です。あるいは、L(unsigned long)を(unsigned Short)に置き換えて、S0..16383をuint16の数値として書き込むこともできます。

おすすめ記事