Как grep текстовый файл, содержащий некоторые двоичные данные?
grep возвращает
Binary file test.log matches
Например
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
Я хочу, чтобы в результате отобразились строки1 и строка3 (всего две строки).
Можно ли использовать tr
преобразовать непечатаемые данные в читаемые данные, чтобы grep снова работал?
Ответы
Ответ 1
Вы можете запустить файл данных с помощью cat -v
, например
$ cat -v tmp/test.log | grep re
line1 re ^@^M
line3 re^M
который затем может быть впоследствии обработан для удаления нежелательной почты; это наиболее похоже на ваш запрос об использовании tr
для задачи.
Ответ 2
Один из способов - просто обрабатывать двоичные файлы как текст в любом случае, с 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
- шестнадцатеричный код для символа. Вы можете просто настроить printf
для любого стиля вывода, который вы хотите.
Вы можете увидеть эту программу в действии здесь, где она:
pax$ printf 'Hello,\tBob\nGoodbye, Bob\n' | ./filterProg
Hello,{{09}}Bob
Goodbye, Bob
Ответ 3
grep -a
Это не может быть проще.
Ответ 4
Вы можете использовать "строки" для извлечения строк из двоичного файла, например
strings binary.file | grep foo
Ответ 5
Вы можете заставить grep посмотреть двоичные файлы с помощью:
grep --binary-files=text
Вы также можете добавить -o
(--only-matching
), чтобы не получить тонны бинарной тарабарщины, которые будут вызывать ваш терминал.
Ответ 6
Начиная с Grep 2.21, двоичные файлы обрабатываются по-другому:
При поиске двоичных данных grep теперь может обрабатывать нетекстовые байты как строки терминаторы. Это может значительно повысить производительность.
Итак, теперь происходит то, что с двоичными данными все нетекстовые байты
(включая новые строки) рассматриваются как терминаторы линий. Если вы хотите изменить это
поведение, вы можете:
-
используйте --text
. Это гарантирует, что только новые строки являются терминаторами строк
-
используйте --null-data
. Это гарантирует, что только нулевые байты являются терминаторами строк
Ответ 7
Как уже сказал Джеймс Селвакумар, grep -a
делает трюк. -a или -text заставляет Grep обрабатывать входной поток как текст.
См. Manpage http://unixhelp.ed.ac.uk/CGI/man-cgi?grep
попробовать
cat test.log | grep -a somestring
Ответ 8
вы можете сделать
strings test.log | grep -i
это преобразует вывод в качестве прочитанной строки в grep.
Ответ 9
grep -a заставит grep искать и выводить из файла, который grep считает двоичным. grep -a re test.log
Ответ 10
Вы также можете попробовать инструмент Word Extractor. Word Extractor можно использовать с любым файлом на вашем компьютере для разделения строк, содержащих человеческий текст/слова из двоичного кода (exe-приложения, библиотеки DLL).