Как к grep названиям файлов, которые содержат одновременно несколько слов

Я сделал следующее:

for i in ~/files/*; do cat $i | grep -e word1 -e word2; done

Вывод был: все значения, которые содержат word1 и вместе с ним - все файлы, которые содержат word2. Не только, которые содержат их обоих. И я хотел имена файлов также, не просто оценивает.

0
задан 16 November 2017 в 07:38

2 ответа

В целом можно использовать grep -H опция к “[p] rint имя файла для каждого соответствия”.

Это найдет строки, которые содержат word1 или word2:

grep -HE "word1|word2" ~/files/* 2>/dev/null

Если Вы хотите найти строки с word1 и word2, вместо этого сделайте:

grep -HE "word1.*word2|word2.*word1" ~/files/* 2>/dev/null

Отправка stderr к темному забвению с 2>/dev/null предотвращает grep от вывода бесполезных сообщений об ошибках, например, если один из подобранных файлов является каталогом.

3
ответ дан 1 November 2019 в 05:14

grep обычно строки печати, соответствующие любому из обеспеченных шаблонов. Для печати строк, соответствующих нескольким шаблонам, передайте вывод по каналу одного grep другому:

grep word1 | grep word2

Для многих файлов:

grep word1 ~/files/* | grep word2

Никакая потребность в цикле или cat.

Это не может работать правильно на файлы, имена которых содержат word2. В этом случае объедините шаблоны вручную в единственный grep:

grep -e 'word1.*word2' -e 'word2.*word1' ~/files/*

Когда нескольким файлам предоставляют grep, это печатает имя файла по умолчанию. Для принуждения этого для единственного имени файла использовать -H:

-H, --with-filename
      Print the file name for each match.  This is  the  default  when
      there is more than one file to search.

Если бы Вы получаете ошибку о списке аргументов, являющемся слишком длинным, и каталог не содержит подкаталоги, все еще сказал бы я grep рекурсивно вызывать:

grep -R -e 'word1.*word2' -e 'word2.*word1' ~/files
2
ответ дан 1 November 2019 в 05:14

Другие вопросы по тегам:

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