BSD版だけ?odの便利な使い方
文字のバイナリ列を調査する必要になり、どうしようかなあと思っていたが、odコマンドが便利だったのを思い出した。
バイナリデータを扱う場合、シェル芸勉強会で時々出てくるのはxxdコマンド。これはvimに付属のコマンドで、バイナリファイルを編集する時にフィルタとして使うらしい。
しかし昔からのodコマンドにも、便利な使い方がある。日本後などマルチバイト文字コード絡みの問題がある時、バイト列の便利な確認方法があるのだ。ただこの使い方、BSD版?のodコマンドでしか出来ないみたい。MacなOSXのodコマンドもBSD版みたいでオケ。
LInuxディストリビューションに付属している、GNU版のodコマンドや、Homebrewで入れるcoreutilsのgodコマンドでは出来ない。どうにかして出来ないか、誰か知ってる??
まずは-c
オプションで文字列が出力される。この時BSD版だと日本語をそのまま表示してくれるのだ。
$ echo ぱぴろん | od -c
0000000 ぱ ** ** ぴ ** ** ろ ** ** ん ** ** \n
0000015
次に-t x1
オプション。これで1バイトづつ16進数で出力される。
$ echo ぱぴろん | od -t x1
0000000 e3 81 b1 e3 81 b4 e3 82 8d e3 82 93 0a
0000015
これらのオプションを併用すると、下記のような出力になる。日本語文字とバイト列の比較が一目瞭然。UTF-8だと日本語って3バイトなんだなーってのがよくわかる。
$ echo ぱぴろん | od -c -t x1
0000000 ぱ ** ** ぴ ** ** ろ ** ** ん ** ** \n
e3 81 b1 e3 81 b4 e3 82 8d e3 82 93 0a
0000015
odコマンド実行時に、環境変数LANGを適切に指定すると、SJISやEUCでも表示してくれる。2バイトになるんだね。
## nkf -s でSJISにしてみる
$ echo ぱぴろん | nkf -s | LANG=ja_JP.SJIS od -c -t x1
0000000 ?? ** ?? ** ?? ** ?? ** \n
82 cf 82 d2 82 eb 82 f1 0a
0000011
## nkf -e でEUCにしてみる
$ echo ぱぴろん | nkf -e | LANG=ja_JP.eucJP od -c -t x1
0000000 ?? ** ?? ** ?? ** ?? ** \n
a4 d1 a4 d4 a4 ed a4 f3 0a
0000011
端末の表示文字コードを変更すれば正しい日本語で表示してくれるが、最後にUTF-8に戻してやっても良い。シェル芸になってた。
$ echo ぱぴろん | nkf -s | LANG=ja_JP.SJIS od -c -t x1 | nkf -w
0000000 ぱ ** ぴ ** ろ ** ん ** \n
82 cf 82 d2 82 eb 82 f1 0a
0000011
$ echo ぱぴろん | nkf -e | LANG=ja_JP.eucJP od -c -t x1 | nkf -w
0000000 ぱ ** ぴ ** ろ ** ん ** \n
a4 d1 a4 d4 a4 ed a4 f3 0a
0000011
・・・ということで、トラブルシューティングとかにも便利かも!?
追記
2016年6月18日に開始された第23回シェル芸勉強会で、Q1の元データにBOMが付いていた。どうなってるか確認するのに、マルチバイト対応のodコマンド使うと分かりやすいかもしれない。
昨日のシェル芸問題Q1で、元データのCSVがBOM付きだった。MacやFreeBSDなどのBSD系OSに付属なodコマンドはマルチバイトテキストの扱いをサポートしてるのでこんな感じで分かりやすかもしれない!? #シェル芸 pic.twitter.com/RUKoJjBbGA
— ぱぴろん (@papiron) 2016年6月19日