Как 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).