Найти текстовые файлы, содержащие 2 термина (в любом порядке, в любой строке)

Вы не можете использовать mkfifoдля копирования или перемещения файлов, нет. mkfifoсоздает именованный канал. Вы можете использовать канал для организации передачи данных в другое место, и иногда именованный канал является единственным или более удобным способом. Некоторые решения, использующие mkfifo, можно найти на этом сайте . Но канал обычно бесполезен, если вы только хотите, чтобы данные заканчивались в другом месте :, для этого достаточно перенаправления.

Если вы хотите извлечь файлы из tar-архива и поместить их в место, отличное от пути внутри архива, именованные каналы вам совсем не помогут. Вместо этого используйте параметр --transformGNU tar или параметр -sBSD tar или pax, чтобы переписать пути к файлам во время извлечения.

1
21.04.2020, 01:12
1 ответ

TL&DR

Примечание.:Вы должны сами проверить, какой из них самый быстрый.

grep -rlzE '(TermOne.*TermTwo)|(TermTwo.*TermOne)'

find. -type f -exec grep -q 'TermOne' {} \; \
               -exec grep -q 'TermTwo' {} \; \
               -print

awk '/TermOne/{if(p==0)p=1; if(p==2)p=3}
     /TermTwo/{if(p==0)p=2; if(p==1)p=3}
     p==3{print FILENAME;p=0;nextfile}'./*

Один файл

Невозможно построить регулярное выражение, которое могло бы сопоставлять две отдельные строки в файле.

Можно искать два термина с любым чередованием:

grep -E '(TermOne.*TermTwo)|(TermTwo.*TermOne)' file

или просмотр вперед:

grep -P '(?=.*TermOne)(?=.*TermTwo)' file

но только если два термина находятся в одной строке

Также можно сделать так, чтобы весь файл действовал как один файл (, если файл не содержит NUL. Текстовые файлы Unix не )с параметром GNU grep -z:

grep -zE '(TermOne.*TermTwo)|(TermTwo.*TermOne)' file

Невозможно использовать -zс -Pодновременно, поэтому на сегодняшний день невозможны никакие упреждающие решения.

Другая альтернатива — выполнить grep дважды:

<file grep 'TermOne' | grep -q 'TermTwo'

Код выхода всего канала будет сигнализировать 0, только если оба термина были найдены в одном файле.

Или, используя awk:

awk '/TermOne/{if(p==0)p=1; if(p==2)p=3}
     /TermTwo/{if(p==0)p=2; if(p==1)p=3}
     p==3{print "both terms found"; exit}' file

список файлов

Первые два приведенных выше решения будут работать для рекурсивного вывода списка всех файлов путем добавления параметров-r(recursive, после чего нет необходимости в имени файла )и-l(списка совпадающих имен файлов ).

grep -rlzE '(TermOne.*TermTwo)|(TermTwo.*TermOne)'

Или, используя find (два вызова grep):

find. -type f -exec grep -q 'TermOne' {} \; -exec grep -q 'TermTwo' {} \; -print

Или, используя awk (, глобус будет включать только PWD):

awk '/TermOne/{if(p==0)p=1; if(p==2)p=3}
     /TermTwo/{if(p==0)p=2; if(p==1)p=3}
     p==3{print FILENAME;p=0;nextfile}'./*
1
19.03.2021, 02:27

Теги

Похожие вопросы