2015-05-15 6 views
3

текущих команды я использую для поиска некоторых шестнадцатеричных значений (например 0A 8b 02) включают:Рекурсивно искать каталог двоичных файлов для шестнадцатеричной последовательности?

find . -type f -not -name "*.png" -exec xxd -p {} \; | grep "0a8b02" || xargs -0 -P 4

Можно ли улучшить это с учетом следующих целей:

  • поиск файлов рекурсивно
  • дисплей смещения и имя файла
  • исключить некоторые файлы с определенными расширениями (выше пример не будет искать .png файлы)
  • скорость: поиск должен обрабатывать 200000 файлов (около 50КБ до 1МБ) в непосредственно на общую сумму ~ 2 Гб.

Я не уверен, если xargs работает правильно для 4-х процессоров. Также у меня возникают трудности с печатью имени файла, когда grep находит совпадение, так как он передается по каналам от xxd. Какие-либо предложения?

+0

Я бы написал сценарий для grepping одного бинарного файла (который печатает имя файла при успехе) и использует этот скрипт в 'find | xargs'. Вы находитесь в zsh, поэтому трудно определить функции в подоболочке. Если вы настроены иметь все в одном скрипте, вы можете использовать bash вместо этого, что позволяет вам экспортировать функцию. – 4ae1e1

+0

Итак, учитывая то, что у меня есть ... невозможно даже вывести имя файла? –

+0

Было бы довольно простое решение, если бы последовательности байтов поиска _never_ включали '0xa' (т. Е. Новые строки) - но это звучит так, как они могут, правильно? Кроме того, вы используете утилиты _GNU_ (Linux)? – mklement0

ответ

2

IF:

  • у вас есть GNUgrep
  • И шестигранные байтов вы ищете никогда не содержат новой строки (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, но они работают в zshksh).
      • гну 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 всегда делает последний, к сожалению,); Кроме того, полезно только сообщать о самих матчах здесь, так как попытка распечатать всю строку приведет к непредсказуемым длинным выходным линиям, учитывая, что нет понятия линий в двоичных файлах; в любом случае, вывод байтов из двоичного файла может вызвать странное поведение рендеринга в терминале.

+0

Далее [этот блог] (https://www.topbug.net/blog/2013/04/14/install-and-use-gnu-command-line-tools-in-mac-os-x/) при установке GNU 'grep', у меня все еще есть проблемы: работает простой [' ggrep -P'] (http://www.commandlinefu.com/commands/view/5959/grep-binary-hexadecimal-patterns), однако я не смог заставить вашу команду вернуть что-либо из простого поиска '00'. Я открыт для * любого * решения, используя BSD 'grep', если это возможно для вас. Это не должна быть одна строка, сценарий отлично работает для меня. –

+0

Просто отметить, что домородок устанавливает gnu grep как 'ggrep'. Запуск 'ggrep --version' дает' (GNU grep) 2.21'. Можно ли также отображать n байтов вперед/назад по смещенному смещению? –

+0

@VeraWang: Это ограничение _shell_, что вы не можете передавать значения, которые включают NUL ('0x0') в качестве _argument_. С помощью _GNU_ Grep вы можете обойти это, сохранив последовательность байтов в _file_, а затем используя этот файл с '-f'. К сожалению, этот метод не работает с _BSD_ Grep. – mklement0

 Смежные вопросы

  • Нет связанных вопросов^_^