今回もddです。AB入れ替え(上下1Byte入れ替え)します。
入力ファイルとして、数値1~10のバイナリを以下のようにして作成。
takk@deb9:~/tmp$ seq 10 | perl -ne 'print chr' > in.bin takk@deb9:~/tmp$ od -tx1 -An in.bin 01 02 03 04 05 06 07 08 09 0a takk@deb9:~/tmp$
2Byte毎に上下1Byteを入れ替えます。conv=swabを指定するだけなので非常に簡単です。
takk@deb9:~/tmp$ cat in.bin | dd conv=swab > out.bin 0+1 レコード入力 0+1 レコード出力 10 bytes copied, 0.000530802 s, 18.8 kB/s takk@deb9:~/tmp$ od -tx1 -An out.bin 02 01 04 03 06 05 08 07 0a 09 takk@deb9:~/tmp$
さて、dd以外のコマンドを使ってAB変換してみましょう。
sedでやってみます。
takk@deb9:~/tmp$ cat in.bin | sed 's/\(.\)\(.\)/\2\1/g'> out2.bin takk@deb9:~/tmp$ od -tx1 -An out.bin 02 01 04 03 06 05 08 07 09 0a takk@deb9:~/tmp$
あれ、できないです。上記の行末の0aが改行コードなので、sedでは置換から除外されてしまいます。
セパレータを改行でなくNULLにする-zオプションを指定すれば、このデータなら変換できますが、
takk@deb9:~/tmp$ cat in.bin | sed -z 's/\(.\)\(.\)/\2\1/g'> out2.bin takk@deb9:~/tmp$ od -tx1 -An out2.bin 02 01 04 03 06 05 08 07 0a 09 takk@deb9:~/tmp$
-zオプションを使ったところで、NULL(0)の方が無視されてしまいます。
takk@deb9:~/tmp$ echo -ne "\x0\x1\x2\x3" >in2.bin takk@deb9:~/tmp$ od -tx1 -An in2.bin 00 01 02 03 takk@deb9:~/tmp$ cat in2.bin | sed -z 's/\(.\)\(.\)/\2\1/g' > out2.bin takk@deb9:~/tmp$ od -tx1 -An out2.bin 00 02 01 03 takk@deb9:~/tmp$
ということで、一旦テキストに変換してからバイナリに戻すことにします。
xxdコマンドを使うと、ダンプ時に簡単に上下1Byteを入れ替えてくれます。
takk@deb9:~/tmp$ cat in.bin | xxd -c2 -e | cut -d' ' -f2 0201 0403 0605 0807 0a09 takk@deb9:~/tmp$
そして、さらにxxdはダンプ結果をバイナリに戻すこともできるので、 -rオプションを使って戻してみます。
takk@deb9:~/tmp$ cat in.bin | xxd -c2 -e | cut -d' ' -f2 | xxd -r -p > out3.bin takk@deb9:~/tmp$ od -tx1 -An out3.bin 02 01 04 03 06 05 08 07 0a 09 takk@deb9:~/tmp$
やりたいことは簡単なのに、ワンライナー長すぎです。
まあやっぱり、AB入れ替えを使う機会があるなら、ddコマンドでいいですね。
コメント