Intereting Posts
HTTP-клиент, сохраняющий метаданные загрузки xdg-open запускает как hexchat, так и Firefox Бесконечное журналирование ошибок при голосовании: не удалось установить блокировку автозапуска печать строки "canonical print-escaped form" Перемещение / загрузка на новый раздел создает: файл '/boot/grub/i386-pc/normal.mod' не найден разбивать файл на несколько частей Можно загрузить все пакеты из «groupinstall», а затем запустить (yum –nogpgcheck localinstall *. Rpm)? Пользовательские привилегии Mysql: Только таблица CREATE Блокировка iptables с интернет-стороны на eth1? Ошибка бросков Bash, строка 8: $ 1: несвязанная переменная Невозможно выполнить KDE Dolphin из веб-скрипта PHP, но работает для всех других программ X Сетевой менеджер исчез Сравните 2 файла, если он находится между диапазоном чисел настройка почтовой системы Как запустить приложение в полноэкранном режиме без загрузки среды рабочего стола IceWM?

выполнение нескольких greps в одной команде find

Я хочу использовать команду find для поиска файлов, содержащих несколько шаблонов одновременно.

Я попробовал что-то вроде этого:

find . -name "*.xml" -exec grep -iH keyword1 + && grep -iH "keyword2" {} \; 

Но приведенная выше команда не работает.

Можно ли это сделать в bash?

Насколько я понимаю, вы хотите перечислить файлы, содержащие как «keyword1», так и «keyword2». Для этого вы можете использовать два теста -exec следующим образом:

 find . -name "*.xml" -exec grep -iq keyword1 {} \; -exec grep -iH keyword2 {} \; 

Это будет запускать второй grep условно – если первый возвращает true. Параметр -q предотвращает вывод из первого grep , поскольку он перечисляет все файлы, которые содержат только «keyword1».

Поскольку опция -H выводит совпадающую строку вместе с именем файла, вы, вероятно, захотите использовать -l вместо этого. Так

 find . -name "*.xml" -exec grep -iq keyword1 {} \; -exec grep -il keyword2 {} \; 

Это даст аналогичный результат тому, что предложил Калеб, но без необходимости дополнительного -print .

Во-первых, чтобы сделать это с помощью find, вы добавите второй аргумент -exec . Каждый аргумент может выполнять только одну команду. Если вам нужно выполнить несколько действий, вам придется использовать хак, сделав одну команду оболочкой и запустив несколько команд. Здесь он find работу:

 find . -name "*.xml" -exec grep -qi "keyword1" {} \; -exec grep -qi "keyword2" {} \; -print 

Обратите внимание, что я использовал опцию -print для вывода имен файлов вместо того, чтобы grep делать это и использовал параметр -q grep, чтобы поместить его в бесшумный режим, чтобы он просто выдавал код возврата, который можно использовать, чтобы найти, чтобы сообщить если результат был правдой или нет, перейдите к нему. Если он достигнет последнего шага (что означает, что оба файла совпали), он печатает вывод.

Однако это неэффективно, потому что grep действительно должен сканировать все файлы дважды. Если бы вы имели в виду ваш вопрос буквально, это должно было бы сделать, но если вы хотели найти файлы, содержащие ЛЮБОЙ из строк, вы можете использовать grep для поиска обоих шаблонов за один проход следующим образом:

 find . -name "*.xml" -exec grep -qi -e "keyword1" -e "keyword2" {} \; -print 

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

Или просто используйте egrep:

find . -name "*.xml" -exec egrep -iH "keyword1|keyword2" {} \;