Я сделал следующее:
for i in ~/files/*; do cat $i | grep -e word1 -e word2; done
Вывод был: все значения, которые содержат word1 и вместе с ним - все файлы, которые содержат word2. Не только, которые содержат их обоих. И я хотел имена файлов также, не просто оценивает.
В целом можно использовать 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
от вывода бесполезных сообщений об ошибках, например, если один из подобранных файлов является каталогом.
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