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

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

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

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

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

6 ответов

Здесь будут найдены строки, содержащие word1 или word2:

for i in ~/files/*; do
  echo "Matches in file $i:"
  grep -E "word1|word2" "$i"
done

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

for i in ~/files/*; do
  echo "Matches in file $i:"
  grep word1 "$i" | grep word2
done
3
ответ дан 22 May 2018 в 16:11
  • 1
    Полезное различие между И и ИЛИ. Благодарю. И как я могу получить имена файлов, а не только выходные данные greps. – Josef Klimuk 16 November 2017 в 18:49
  • 2
    @JosefKlimuk С простым echo перед ним, см. Мое редактирование. Однако для полезной опции grep (и лучше!) [F3] см. Ответ муру. – dessert 16 November 2017 в 18:51

В общем случае вы можете использовать опцию 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 предотвращает вывод f10 из бесполезных сообщений об ошибках, например если один из файлов сопоставления - это каталог.

3
ответ дан 18 July 2018 в 03:11

В общем случае вы можете использовать опцию 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 предотвращает вывод f10 из бесполезных сообщений об ошибках, например если один из файлов сопоставления - это каталог.

3
ответ дан 24 July 2018 в 17:46

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.

Если вы получаете сообщение об слишком длинном списке аргументов, и каталог не содержит подкаталогов, я бы все же сказал [ f11] для рекурсии:

grep -R -e 'word1.*word2' -e 'word2.*word1' ~/files
2
ответ дан 22 May 2018 в 16:11
  • 1
    Слишком много файлов, поэтому я получил: «Список слишком длинный» или что-то вроде этого, поэтому я пошел в цикл. Другое дело: если я буду делать grep для grep - он будет работать только с выходом первого grep, а не с оригинальным файлом. – Josef Klimuk 16 November 2017 в 18:44
  • 2
    @JosefKlimuk видит последнюю команду для этого случая. И добавьте такие ошибки на вопрос, пожалуйста. – muru 16 November 2017 в 18:49
  • 3
    @JosefKlimuk - вот и все. Если вы хотите, чтобы линии соответствовали обоим шаблонам, вам придется либо использовать сложное регулярное выражение, как в третьей команде, либо передать трубку другому grep. – muru 16 November 2017 в 18:50

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
ответ дан 18 July 2018 в 03:11

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
ответ дан 24 July 2018 в 17:46
  • 1
    Слишком много файлов, поэтому я получил: «Список слишком длинный» или что-то вроде этого, поэтому я пошел в цикл. Другое дело: если я буду делать grep для grep - он будет работать только с выходом первого grep, а не с оригинальным файлом. – Josef Klimuk 16 November 2017 в 18:44
  • 2
    @JosefKlimuk видит последнюю команду для этого случая. И добавьте такие ошибки на вопрос, пожалуйста. – muru 16 November 2017 в 18:49
  • 3
    @JosefKlimuk - вот и все. Если вы хотите, чтобы линии соответствовали обоим шаблонам, вам придется либо использовать сложное регулярное выражение, как в третьей команде, либо передать трубку другому grep. – muru 16 November 2017 в 18:50

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

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