Совпадение всех шаблонов из файла сразу

У меня есть 2 файла: args и text . Например:

args: [содержит аргументы скрипта]

 life happy horse 

текст:

 The horse has a happy life. Life is fun. Kids are happy. 

Мне нужна команда, которая печатает строки из text , содержащего все шаблоны из args . В этом случае: The horse has a happy life.

4 Solutions collect form web for “Совпадение всех шаблонов из файла сразу”

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

 patterns=$(sed 's/;/\\;/' <args | tr '\n' ';' | sed 's/;$//') agrep "$patterns" text 

Мутирование для создания списка шаблонов объединяет их вместе с точкой с запятой. Тем не менее, мы не должны иметь точку с запятой в конце списка, поэтому ее удаляем, а также любой шаблон, содержащий точку с запятой, должен иметь этот символ, поэтому он не рассматривается как оператор И. Используйте echo "$patterns" чтобы увидеть, как конвертируется файл args .

Используйте awk .

 ~$ cat textlist.txt | awk '/life/ && /happy/ && /horse/ { print; }' The horse has a happy life 

textlist.txt – список предложений, которые вы указали.

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

 # for a in $(cat args); do regex="$regex | grep '$a'"; done # eval cat text "$regex" The horse has a happy life. 

Обычно grep с параметром -f печатает строки по меньшей мере с одним шаблоном, например

 grep -f args.txt file.txt 

В вашем случае это не сработает.

Таким образом, чтобы печатать строки, которые соответствуют всем шаблонам одновременно, вы можете попробовать эту команду:

while read n text; do [ $n -eq $(wc -l < args.txt) ] && echo $text; done < <(while read patt; do grep "$patt" text.txt; done < args.txt | sort | uniq -c)

Объяснение:

  1. Внутренний цикл while будет печатать все строки, которые соответствуют хотя бы одному шаблону в text.txt используя список шаблонов из файла args.txt .
  2. Затем этот список сортируется ( sort ) и подсчитывается для количества вхождений ( uniq -c ).
  3. Внешний цикл while будет печатать только строки, которые имеют такое же количество вхождений, что и число шаблонов в args.txt (которое равно 3).

Другим подходом было бы удаление всех строк, которые не соответствуют хотя бы одному шаблону.

Вот решение, использующее редактор Ex / Vim, изменяющий файл на месте:

 while read patt; do ex +"v/$patt/d" -scwq text.txt; done < args.txt 

Примечание. Это приведет к удалению ненужных строк из файла.

Вот более короткая версия, которая будет печатать результат только на экране:

 ex $(xargs -I% printf "+v/%/d " < args.txt) +%p -scq! text.txt 

Изменить +%p -scq! to -scwq чтобы сохранить его на месте в файле.


И вот решение, определяющее псевдоним оболочки:

 alias grep-all="</dev/stdin $(xargs printf '|grep "%s"' < args.txt)" 

Использование образца:

 grep-all file.txt 

См. Также: Как запустить grep с несколькими шаблонами И? и как grep для двух слов, существующих в одной строке?

  • как избавиться от нежелательных линий? в то время как цикл?
  • Как определить, присутствует ли строка в stdout, не влияя на вывод?
  • Проблема при чтении содержимого файла журнала каждые 30 минут
  • Смутно о границе слова
  • Как перенаправить вывод из команды find (использующей grep) в файл журнала?
  • Есть ли более быстрый способ получить этот выходной файл в Linux?
  • Как вернуть имя файла и номер строки с помощью find ... -exec grep?
  • grep: Какие * шаблоны * соответствуют, а не какой текст?
  • Использование Perl-совместимого регулярного выражения с GNU grep -P
  • Как использовать регулярное выражение BRE или ERE для соответствия шаблону, который не имеет определенной строки
  • Подстановка на месте для строк, соответствующих некоторому шаблону в заданном наборе файлов
  • Linux и Unix - лучшая ОС в мире.