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

場合によっては、この方が見やすいかもしれません。


あまり上手い例は出せませんでしたが、文字コードや特殊文字の関係で発生したエラーの原因調査のような状況で役立つので、知っていて損はないと思います。


いいなと思ったら応援しよう!