od と xxd について
日常的には使わないとしても、何かの折には役に立つ、ということで、備忘録的に書いておくことにしました。
以下2つのコマンドについてです。
od
入力を8進数や16進数などに変換するxxd
入力を16進数に変換したり、戻したりする
普通に文字を echo して、それが od や xxd でどのようになるのか確認していきます。
$ echo "hello"
hello
od
入力が指定した○○進数に変換されます。
$ echo "hello" | od -t x1 -c
0000000 68 65 6c 6c 6f 0a
h e l l o \n
0000006
-t は出力の形式を指定するオプションです。
x1 は、16進数で1バイトずつの出力を意味します。
-c は対応する文字を表示するオプションです。
改行コードなど、通常は表示されないものも見えるようになります。
出力に含まれる 0000000 や 0000006 はアドレスなのですが、正直なところ何のためのものなのかよく分かっていません。
というわけで、アドレスを非表示にしました。
$ echo "hello" | od -t x1 -c -A n
68 65 6c 6c 6f 0a
h e l l o \n
-A はアドレスの形式を指定するオプションです。
n を指定すると、アドレスは非表示になります。
xxd
入力が16進数に変換されます。
$ echo "hello" | xxd -p
68656c6c6f0a
-p はプレーン表示のオプションです。
-p を付けないと、出力は以下のようになります。
$ echo "hello" | xxd
00000000: 6865 6c6c 6f0a hello.
xxd では、-r オプションによって、16進数を文字に戻すこともできます。
$ echo "68656c6c6f0a" | xxd -p -r
hello
上記は16進数をつなげて入力していますが、od で16進数に変換したスペース入りの状態でも、そのまま扱うことが可能です。
$ echo "68 65 6c 6c 6f 0a" | xxd -p -r
hello
使いどころ
では、16進数への変換が何の役に立つのかですが、改行コードや半角スペースなど、通常は見えない・見えにくい、特殊な文字の存在を特定する際に活用できます。
例えば、echo の末尾には改行コードが付けられ、ファイルに書き込むときにもそのまま、最後に改行が入っているということを明示的に確認できます。
$ echo "hello" > test.txt
$ cat test.txt
hello
$ cat test.txt | od -t x1 -c -An
68 65 6c 6c 6f 0a
h e l l o \n
echo -n で末尾の改行がなくなることも明示的に確認することができます。
$ echo -n "hello" > test.txt; cat test.txt | od -t x1 -c -An
68 65 6c 6c 6f
h e l l o
以下のようなテキストファイルが、実は半角スペースまみれだと分かったりします。(それくらいなら vi で開いても分かりますが)
$ cat test.txt
hello
$ cat test.txt | od -t x1 -c -An
68 65 6c 6c 6f 20 20 20 20 20 20 20 0a
h e l l o \n
ちなみに、ずっと -c を使っていましたが、代わりに -a にすると、以下のようになります。
$ cat test.txt | od -t x1 -a -An
68 65 6c 6c 6f 20 20 20 20 20 20 20 0a
h e l l o sp sp sp sp sp sp sp nl
場合によっては、この方が見やすいかもしれません。
あまり上手い例は出せませんでしたが、文字コードや特殊文字の関係で発生したエラーの原因調査のような状況で役立つので、知っていて損はないと思います。