大容量ログファイルでテキスト以外のバイナリ文字を含むすべての行番号を検索する

大容量ログファイルでテキスト以外のバイナリ文字を含むすべての行番号を検索する

テキスト以外の文字を含む大容量ログファイルがあります。 grepを使用して検索した結果は次のとおりです。

Binary file (standard input) matches

grep -aを使用すると、テキスト以外の文字を含む行をスキップできます。

これで、テキスト以外の文字を含むすべての行をどのように見つけることができますか?

ベストアンサー1

GNUがgrepテキスト以外のコンテンツと見なすことは、バージョンとロケールによって異なります。

最初の近似では、次のことを試すことができます。

grep -anPe '^((?!.*$)|.*\0)' < file.log

つまり、NUL文字とゼロバイトを含む行を見つけます(この状況の原因である可能性があります)。バイナリファイルO_APPENDなしで一部のプロセスで書き込み用に開くときにログファイルが切り捨てられたか文字でない場合(ロケールにマルチバイト文字セット(UTF-8など)があり、一部の行が別のA文字セット出力で終わる場合)することができます)。

GNUがPCREサポート(for)grepで構築されているとします。-P

その出力を、sed -n lまたは(オプションは省略することもできます)のようなものにパイプして原因を特定しようとすることができます。hexdump -Cod -vtc -tx1-ngrepバイナリ情報。

grep -aこの行はスキップせずにGNUにファイルとして扱わないように指示することですgrepバイナリ特別な。ゼロバイトまたは文字以外の行を含む行は、パターンと一致する場合は報告され続けます。

少なくともLinuxおよびほとんどの基本ファイルシステムでは、ファイルが希薄であるかどうか、つまりゼロバイトでいっぱいに見える未割り当て部分(穴)があるかどうかを確認できます。

perl -le '
  seek STDIN,0,4 or die; $hole = tell STDIN;
  seek STDIN, $hole, 3 and $data = tell STDIN;
  seek STDIN, 0, 2; $end = tell STDIN;
  if ($hole != $end) {
    print "at least one hole at offset $hole, length ".(($data||$end) - $hole)
  }' < file.log

間隔に1つ以上の完全なファイルシステムブロック(通常4KiB)が含まれている場合、ファイルシステムが作成されます。これらの穴の両側にはより多くのNULバイトがあります。

おすすめ記事