バイナリデータを含むテキストファイルをgrepする方法


122

grepが戻る

バイナリファイルtest.logの一致

例えば

echo    "line1 re \x00\r\nline2\r\nline3 re\r\n" > test.log  # in zsh
echo -e "line1 re \x00\r\nline2\r\nline3 re\r\n" > test.log  # in bash
grep re test.log

結果にline1とline3(合計2行)が表示されることを望みます。

それは使用することができtr、再びgrepの仕事をできるように、読み取り可能なデータに印刷できないデータを変換しますか?


バイナリファイルからバイナリ文字を除外し、テキスト文字(読み取り可能)のみを保持するプログラムがあることに注意してください。ここ: soft.tahionic.com/download-words_extractor/index.html
InTheNameOfScience

すみません、しかし...あなたが欠落していない-eecho、コマンド?
Sopalajo de Arrierez 2014

'zsh'を使用する場合、-eがなくても問題ありません。「bash」を使用する場合は、「-e」を追加する必要があります。
ダニエルYCリン

回答:


67

あなたは介してデータファイルを実行することができますcat -v例えば、

$ cat -v tmp/test.log | grep re
line1 re ^@^M
line3 re^M

その後、さらに後処理してジャンクを削除できます。これはtr、タスクの使用に関するクエリに最も似ています。


5
私の問題を解決しました。ありがとう!ここでは何man catについて述べている-v-v, --show-nonprinting use ^ and M- notation, except for LFD and TAB
tommy.carstensen

これはパイプラインでも機能することに注意してください。例えばset | cat -v | grep variable
funroll

1
grep --textが機能するのに、なぜこれを使用するのですか?これはもっと複雑に見えます。
Michael Haefele 2017年

grep --text常に機能するとは限りません。CTRL + Dをファイル終了文字として扱います。したがって、バイナリファイルにそれがある場合、grepは早く終了します。
トミー


91

1つの方法は、とにかく単純にバイナリファイルをテキストとして扱うことですgrep --textが、これにより、バイナリ情報が端末に送信される可能性があります。出力ストリームを解釈する端末(VT / DECなど)を実行している場合、これは実際に良い考えではありません。

または、tr次のコマンドを使用してファイルを送信できます。

tr '[\000-\011\013-\037\177-\377]' '.' <test.log | grep whatever

これにより、スペース文字(改行を除く)未満および126より大きいものはすべて文字に変更され.、印刷可能ファイルのみが残ります。


すべての「不正な」文字を別の文字に置き換えたい場合は、次のCプログラムのようなものを使用できます。これは、古典的な標準入力フィルターです。

#include<stdio.h>
int main (void) {
    int ch;
    while ((ch = getchar()) != EOF) {
        if ((ch == '\n') || ((ch >= ' ') && (ch <= '~'))) {
            putchar (ch);
        } else {
            printf ("{{%02x}}", ch);
        }
    }
    return 0;
}

これ{{NN}}により、NNが表示されます。は、キャラクターの16進コードです。printf必要な出力スタイルに合わせてを調整できます。

あなたはここでそのプログラムが動作しているのを見ることができます:

pax$ printf 'Hello,\tBob\nGoodbye, Bob\n' | ./filterProg
Hello,{{09}}Bob
Goodbye, Bob

このメソッドは、すべてのバイナリ文字を同じ「。」にマッピングします。シンボル。それらを読み取り可能なシンボルにマッピングする他の方法はありますか?
ダニエルYCリン

もちろん、別のフィルタープログラムで実行することもできます。その1つは更新プログラムで提供されています。
paxdiablo

1
tr '[:cntrl:] '.'良いと思います。そして、それは\000-\010\013\014\016-\037\177-\377'あなたのtr構文にあるべきです。
ダニエルYCリン

2
テスト後、tr '[\000-\010\013\014\016-\037\177-\377]' '_'実行可能ですが、cntrlは私の場合には適していません。
ダニエルYCリン

2
catパイプでgrep --texttrなく、パイプでステップを保存できます。これにより、複数のファイルをgrepして、ファイル名参照を出力に保持することもできます。
aaaantoine 2014

33

たとえば、「文字列」を使用して、バイナリファイルから文字列を抽出できます。

strings binary.file | grep foo

ソースは各行にUIDを含むデバッグログだったので、私にとってはうまくいきました。ありがとう。
mbrownnyc 2013

私にとってもうまくいきました。ご回答有難うございます。私の日を保存しました:)
Shekhar 2014年

2
私は@paxdiabloの答えに感謝しますが、簡単に答えて仕事に取り掛かるには、これを誤りにすることはできません。
ウィル2014

paxdiabloソリューションを使用しようとしましたが、期待していた結果は得られませんでした。@moodywoodyあなたのソリューションは素早く簡単で、私が必要とするものを正確に出力します!
justinhartman 2014年

20

次のコマンドを使用して、grepにバイナリファイルを表示させることができます。

grep --binary-files=text

また、-o--only-matching)を追加して、端末を混乱させるような大量のバイナリの意味不明なものを取得しないようにすることもできます。


バイナリガベージを出力する可能性があります。出力がターミナルであり、ターミナルドライバーがその一部をコマンドとして解釈する場合、厄介な副作用が発生する可能性があります。
Daniel YC Lin

を使用し--only-matching、正規表現が任意のバイナリデータと一致しない場合、問題は発生しません。
AB

正規表現が「first。* end」で、バイナリデータに「。*」パターンが含まれている場合、後処理のプロセスを修正できません。まあありがとう。
Daniel YC Lin

16

Grep 2.21以降、バイナリファイルの扱いが異なります。

バイナリデータを検索するとき、grepはテキスト以外のバイトを行末記号として扱うようになりました。これにより、パフォーマンスが大幅に向上します。

つまり、バイナリデータでは、すべての非テキストバイト(改行を含む)が行終了文字として扱われます。この動作を変更する場合は、次のことができます。

  • 使用します--text。これにより、改行だけが行末記号になります。

  • 使用します--null-data。これにより、nullバイトのみが行のターミネーターになります。


5

grep -aは、grepがバイナリであると考えるファイルからgrepを強制的に検索および出力します。grep -a re test.log


3

James Selvakumarがすでに言ったようにgrep -a、トリックを行います。-aまたは--textを指定すると、Grepは入力ストリームをテキストとして処理します。マンページを参照してくださいhttp://unixhelp.ed.ac.uk/CGI/man-cgi?grep

試す

cat test.log | grep -a somestring

2

できるよ

strings test.log | grep -i

これは、出力を読み取り可能な文字列としてgrepに変換します。


0

Word Extractorツールを試すこともできます。Word Extractorをコンピューター内の任意のファイルで使用して、人間のテキストや単語を含む文字列をバイナリコード(exeアプリケーション、DLL)から分離できます。


私の場合、単語抽出機能は必要ありません。行番号を保持する必要があります。
ダニエルYC林

0

これは、「strings」コマンドがインストールされていないシステムで使用したものです

cat yourfilename | tr -cd "[:print:]"

これはテキストを印刷し、印刷できない文字を一気に削除します。「cat -v filename」とは異なり、不要なものを削除するためにいくつかの後処理が必要です。バイナリデータの一部は印刷可能である場合があるため、優れたものの間で意味不明な点がまだあることに注意してください。あなたがそれを使うことができれば、文字列もこの意味不明なものを取り除くと思います。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.