(Хотя приведенное ниже может быть не лучшим решением для этого конкретного случая, я все равно добавил его на случай, если это поможет будущему читателю с подобной проблемой. Ниже приведено решение gawk
, которое может быть полезно для этого варианта использования .)
grep
имеет новую строку в качестве терминатора шаблона. Даже если вы используете -e pattern
, новые строки в строке шаблона приведут к тому, что grep будет обрабатывать параметры как указывающие несколько шаблонов, а не один шаблон, содержащий символы новой строки.
Однако, если ваши шаблоны, разделенные NUL, не содержат символов новой строки, вы можете использовать Gnu xargs
и sed
для создания соответствующего grep
вызова с -e
аргументами командной строки:
sed -z 's/^/-e/' data | xargs -0 grep -zF data2 ...
(Это работает, потому что Gnu grep
переставляет аргументы командной строки, поэтому можно помещать файлы для поиска перед шаблонами. Это не сработает во многих других grep
реализациях.)
Насколько я знаю, не существует обходного пути для шаблонов, которые могут содержать символы новой строки. grep -E
и grep -F
не распознают escape-последовательности ascii и будут молча создавать несколько шаблонов из шаблона, который содержит символ новой строки. grep -P
(другое расширение Gnu, использующее регулярное выражение PCRE) будет правильно обрабатывать встроенные символы новой строки или символы ascii, но допускает только один шаблон.
Полные строки с NUL-завершенными совпадениями без сортировки
В случае, если вас интересуют только точные, полные совпадения строк (-Fx
), вы можете использовать сценарий Gnu Awk вместо сортировки входных данных и шаблонов. Это может быть выигрыш для очень больших входов, которые не помещаются в памяти; сортировка по внешним временным файлам может быть довольно дорогой. Решение Awk использует хеш-таблицу, поэтому сортировка не требуется. (Опять же, это может не сработать на всех Awks, потому что оно основано на установке RS
в NUL.)
awk -v RS=`\0` 'NR==FNR{p[$0] = 1; next;} $0 in p' data data2 ...