web-dev-qa-db-ja.com

バイナリファイルからのASCII文字列の「grep」オフセット

単純に一連のレコードを連結したバイナリデータファイルを生成しています。各レコードは、(バイナリ)ヘッダーとそれに続くバイナリデータで構成されます。バイナリヘッダー内には、80文字のASCII文字列があります。途中のどこかで、ファイルを書き込む私のプロセスが少しめちゃくちゃになり、各レコードが実際にどれくらいの長さであるかを調べて、この問題をデバッグしようとしています。

これ は非常に関連しているように見えますが、Perlが理解できないため、受け入れられた答えを得ることができませんでした。他の答えは、私がコンパイルしたbgrepを指していますが、16進数の文字列をフィードする必要があり、ASCII文字列を指定できるツールがあればそれが見つかります。バイナリデータは、文字列とそれが見つかったバイトオフセットを出力します。

つまり、次のようなツールを探しています。

tool foobar filename

または

tool foobar < filename

そしてその出力は次のようなものです:

foobar:10
foobar:410
foobar:810
foobar:1210
...

例えば一致した文字列と、一致が開始されたファイルのバイトオフセット。この例の場合、各レコードは400バイトの長さであると推測できます。

その他の制約:

  • 正規表現で検索する機能は優れていますが、この問題では必要ありません
  • 私のバイナリファイルは大きい(3.5Gb)ので、可能であればファイル全体をメモリに読み込まないようにしたいと思います。
30
mgilson

これにはstringsを使用できます。

strings -a -t x filename | grep foobar

GNU binutils。

たとえば、/bin/ls--help 発生する:

strings -a -t x /bin/ls | grep -- --help

出力:

14938 Try `%s --help' for more information.
162f0       --help     display this help and exit
26
Thor
grep --byte-offset --only-matching --text foobar filename

--byte-offsetオプションは、一致する各行のオフセットを出力します。

--only-matchingオプションは、一致する各行ではなく、一致するインスタンスごとにオフセットを出力します。

--textオプションを指定すると、grepはバイナリファイルをテキストファイルとして扱います。

次のように短縮できます。

grep -oba foobar filename

GNU grepのバージョンで、デフォルトでLinuxに付属しています。BSDのgrep(Macにデフォルトで付属しています)では動作しません。

30
Hari Menon

同じことをしたかった。ひも| grepが機能し、gsarがまさに必要なツールであることがわかりました。

http://tjaberg.com/

出力は次のようになります。

>gsar.exe -bic -sfoobar filename.bin
filename.bin: 0x34b5: AAA foobar BBB
filename.bin: 0x56a0: foobar DDD
filename.bin: 2 matches found
0
caesun