目的
凄腕 GNU/Linux エンジニアの皆様、ふと日常の中で
任意のバイト列を探したいことはありませんか?
例えば・・・
・ファイル内のNULL文字('\0')の個数を検索したい
・言語設定は LANG=C だけど日本語の「あ」を検索したい
・文字化けしちゃう外国語の文字を検索したい
この記事は、bash 様の力を借りて、このようなケースの手助けをするための記事です。
弊社内でも案外知らない方が多かったので、メモしておきます。
基本テクニック
bashの力を借りる
bash は、以下のようなフォーマットで 16進数表記した任意のバイト列を扱うことができます。
http://linuxjm.sourceforge.jp/html/GNU_bash/man1/bash.1.html より
$'\xXX'
使用例
ファイル内のNULL文字('\0')の個数を検索したい
試しに、バイナリファイル ping コマンド内の NULL文字の個数を検索してみましょう。
149個あるそうです。
$ grep -c $'\x00' `which ping`
149
ターミナルに「あ」を表示
UTF-8 で、ひらがなの「あ」を表示させましょう。(「あ」 Unicode U+3042)
「あ」のバイト列は、0xE38182 です。
$ echo $LANG
ja_JP.UTF-8
$ echo $'\xE3'$'\x81'$'\x82'
あ
言語設定は LANG=C だけど日本語の「こんにちは」を検索したい
「こんにちは」を UTF-8 で表記
「こんにちは」を UTF-8 で表記すると
こ:E3 81 93
ん:E3 82 93
に:E3 81 AB
ち:E3 81 A1
は:E3 81 AF
となります。
iconv のテストファイルから「こんにちは」を検索!
iconv で有名な
文字変換ライブラリ libiconv-1.14 のテストファイルを例にします。
http://www.gnu.org/software/libiconv/
又は
https://github.com/bnoordhuis/libiconv/blob/master/tests/UCS-2BE-snippet.UTF-8 より。
libiconv-1.14/tests/UCS-2BE-snippet.UTF-8 ファイルには、
様々な言語で こんにちは と書かれているようです。
「こんにちは」で grep した結果
$ grep $'\xE3'$'\x81'$'\x93'$'\xE3'$'\x82'$'\x93'$'\xE3'$'\x81'$'\xAB'$'\xE3'$'\x81'$'\xA1'$'\xE3'$'\x81'$'\xAF' UCS-2BE-snippet.UTF-8
Japanese (日本語) こんにちは, コンニチハ
バッチリ検索できましたね!
文字化けする外国語で検索
アラビア語の検索にチャレンジ!
libiconv-1.14/tests/UCS-2BE-snippet.UTF-8 ファイルの 6行目にアラビア語があるのですが、
私のエディタで表示したところ文字化けしちゃいました・・・。
しかし!任意のバイト列として指定してあげれば
相手がアラビア語だろうと、「こんにちは」を grep で検索できるのです。
libiconv-1.14/tests/UCS-2BE-snippet.UTF-8 6行目
Arabic ????? ?????
★★
この5文字を grep しますよー!
バイト列にすると、以下のようです。(全く分からん・・・。)
EF BA 8D
EF BB 9F
EF BA B4
EF BB BC
EF BB A1
※od コマンドでの検索方法は後述
いざ!grep してみましょう!
# コマンド実行
$ grep $'\xEF'$'\xBA'$'\x8D'$'\xEF'$'\xBB'$'\x9F'$'\xEF'$'\xBA'$'\xB4'$'\xEF'$'\xBB'$'\xBC'$'\xEF'$'\xBB'$'\xA1' UCS-2BE-snippet.UTF-8
Arabic ????? ?????
やったね!検索できました☆
バイト列の抽出について
バイト列は od コマンドを使って、以下のように抽出しました。
リトルエンディアン環境なので、
0x00 01 02 03 04 05... は
0100 0302 0504... のように並んでいることにご注意下さい。
より詳しくは、od コマンドの manページ等が参考になります。
OD
http://linuxjm.sourceforge.jp/html/gnumaniak/man1/od.1.html
$ grep Arabic UCS-2BE-snippet.UTF-8 | od -c -x --width=500
0000000 A r a b i c \t \t \t 357 272 215 357 273 237 357 272 264 357 273 274 357 273 241 357 273 213 357 273 240 357 273 264 357 273 234 357 273 242 \n
7241 6261 6369 0909 ★ここ以降★ef09 8dba bbef ef9f b4ba bbef efbc a1bb ef20 8bbb bbef efa0 b4bb bbef ef9c a2bb 000a
実行環境
このメモのコマンド類は、Fedora14 で試しました。(古い・・・。)
最新の Fedora でも動作が変わってないといいなあ。
Fedora14 32bit
bash 4.1.7
grep 2.8