LoginSignup
13
11

More than 5 years have passed since last update.

【16進数】bash様の助けを借りて任意のバイト列を grep する

Last updated at Posted at 2014-06-27

目的

凄腕 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

13
11
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
13
11