IF:
- у вас есть GNU
grep
- И шестигранные байтов вы ищете никогда не содержат новой строки (
0xa
) [1]
- Если они содержат NUL (
0x
) , вы должны указать строку поиска grep
через файл (-f
), а не прямым аргументом.
следующая команда получит вас там, используя пример поиска для 0e 8b 02
:
LC_ALL=C find . -type f -not -name "*.png" -exec grep -FHoab $'\x{0e}\x{8b}\x{02}' {} + |
LC_ALL=C cut -d: -f1-2
Команда grep
производит выходные линии следующим образом:
<filename>:<byte-offset>:<matched-bytes>
который LC_ALL=C cut -d: -f1-2
затем сводится к <filename>:<byte-offset>
Команды почти работает с BSDgrep
, за исключением того, что смещение байта сообщает это неизменно начала линии, что образец был подобран на.
Других слов: байтового смещения будет единственно правильной, если нет перевода строки не предшествует спичку в файле.
Кроме того, BSD grep
не поддерживает указание байтов NUL (0x0
) как часть строки поиска, даже если они предоставлены через файл -f
.
- Обратите внимание, что не будет нет параллельной обработки, но только несколько
grep
вызовов, основанного на использование find
«s -exec ... +
, который, как xargs
, проходит так много имен файлов, которые поместятся по команде линия до grep
сразу.
- Позволяя
grep
поиск последовательности байтов непосредственно, нет необходимости в xxd
:
- Последовательность указана в качестве ANSI C-quoted string, что означает, что управляющие последовательности разлагаются литералы в оболочки, что позволяет Grep чтобы затем найти итоговую строку как литерал (через
-F
), который работает быстрее.
Связанная статья из справочника bash
, но они работают в zsh
(и ksh
).
- гну Grep альтернативой является использование
-P
(поддержка PRCEs, Perl-совместимых регулярных выражений) с предварительно не расширенных управляющих последовательностей, но это будет медленнее: grep -PHoab '\x{0e}\x{8b}\x{02}'
LC_ALL=C
гарантирует что grep
обрабатывает каждый байт как свой собственный символ без применения каких-либо правил кодирования.
-F
обрабатывает поисковые строки как буквальный (а не регулярных выражений)
-H
подставляет соответствующий входного файла для каждой выходной линии; обратите внимание, что Grep делает это неявно, когда дано более 1 файл аргумент
-o
описывает только совпавшие строки (последовательности байт), а не вся линия (концепция линии не имеет никакого значения в бинарных файлах в любом случае) [2]
-a
обрабатывает двоичные файлы, как если бы они были текстовые файлы (без этого, Grep будет только распечатать текст Binary file <filename> matches
для двоичных входных файлов с помощью спичек)
-b
сообщает байт смещения матчей
Если достаточно найти совпадение в данном файле ввода, добавьте -m 1
.
[1] Newlines не может быть использован, так как Grep неизменно относится к новой строки в строке поиска-шаблона в качестве разделяющего множественного поиска шаблонов. Кроме того, Grep - это линия, поэтому вы не можете сопоставлять строки; Опция GNU Grep's -null-data
может разделить входные байты NUL, но только если ваша последовательность байтов поиска также не содержит байтов NUL; вам также нужно будет представлять свои байтовые значения как escape-последовательности в regex в сочетании с -P
- потому что вам нужно использовать escape-последовательность \n
вместо фактической строки перевода.
[2] -o
необходимо сделать -b
отчет байте смещение матча в противоположность тому, что в начале строки (как указано, BSD Grep всегда делает последний, к сожалению,); Кроме того, полезно только сообщать о самих матчах здесь, так как попытка распечатать всю строку приведет к непредсказуемым длинным выходным линиям, учитывая, что нет понятия линий в двоичных файлах; в любом случае, вывод байтов из двоичного файла может вызвать странное поведение рендеринга в терминале.
Я бы написал сценарий для grepping одного бинарного файла (который печатает имя файла при успехе) и использует этот скрипт в 'find | xargs'. Вы находитесь в zsh, поэтому трудно определить функции в подоболочке. Если вы настроены иметь все в одном скрипте, вы можете использовать bash вместо этого, что позволяет вам экспортировать функцию. – 4ae1e1
Итак, учитывая то, что у меня есть ... невозможно даже вывести имя файла? –
Было бы довольно простое решение, если бы последовательности байтов поиска _never_ включали '0xa' (т. Е. Новые строки) - но это звучит так, как они могут, правильно? Кроме того, вы используете утилиты _GNU_ (Linux)? – mklement0