如何grep包含一些二进制数据的文本文件?
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(共两行)。
是否可以使用tr
将不可打印的数据转换为可读的数据,让grep再次工作?
你可以通过cat -v
运行数据文件,例如
$ cat -v tmp/test.log | grep re line1 re ^@^M line3 re^M
然后可以进一步后处理去除垃圾; 这与你使用tr
进行任务的查询最类似。
一种方法是简单地把二进制文件作为文本,用grep --text
但是这可能会导致二进制信息被发送到你的terminal。 如果你运行一个解释输出stream的terminal(如VT / DEC或其他许多terminal),那么这不是一个好主意。
或者,您可以使用以下命令通过tr
发送文件:
tr '[\000-\011\013-\037\177-\377]' '.' <test.log | grep whatever
这将改变任何比空格字符(除了换行符)和任何大于126的东西都变成一个.
字符,只留下printables。
如果你想让每个“非法”字符replace为不同的字符,你可以使用类似下面的C程序,一个经典的标准inputfilter:
#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
是字符的hex代码。 您可以简单地调整printf
以获得所需的任何样式的输出。
你可以看到这个程序在这里的行动,它在哪里:
pax$ printf 'Hello,\tBob\nGoodbye, Bob\n' | ./filterProg Hello,{{09}}Bob Goodbye, Bob
grep -a
它不能简单得多。
例如,您可以使用“string”从二进制文件中提取string
strings binary.file | grep foo
您可以强制grep查看二进制文件:
grep --binary-files=text
你可能还想添加-o
(– --only-matching
),这样你就不会得到大量的二进制乱码,这将会使你的terminal变得困难。
从Grep 2.21开始,二进制文件的处理方式不同 :
当search二进制数据时,grep现在可以将非文本字节视为行终止符。 这可以显着提升性能。
那么现在发生的事情是,对于二进制数据,所有非文本字节(包括换行符)被视为行终止符。 如果你想改变这种行为,你可以:
-
使用
--text
。 这将确保只有换行符是行终止符 -
使用
--null-data
。 这将确保只有空字节是行终止符
正如詹姆斯·塞尔瓦库马尔(James Selvakumar)已经说过的那样, grep -a
做到。 -a或–text强制Grep将inputstream作为文本处理。 见手册http://unixhelp.ed.ac.uk/CGI/man-cgi?grep
尝试
cat test.log | grep -a somestring
你可以做
strings test.log | grep -i
这将转换为可读的string输出到grep。
grep -a将强制grep从grep认为是二进制文件search并输出。 grep -a re test.log
您也可以尝试Word Extractor工具。 Word Extractor可以与计算机中的任何文件一起使用,以将包含人类文本/文字的string与二进制代码(exe应用程序,DLL)分离。