#linux #unix #sed #awk #grep
#linux #unix #sed #awk #grep
Вопрос:
В Linux я хочу выполнить поиск в данном directoy и его вложенных папках / файлах для определенного шаблона включения и исключения.
find /apps -exec grep "performance" -v "warn" {} /dev/null ;
Это повторяет множество строк, из которых выполняется поиск. Я не хочу этого, я хотел бы найти файлы, содержащие performance, которые не содержат warn. Как мне это сделать?
Ответ №1:
Очень близко к тому, что у вас уже есть:
find /apps -exec grep "performance" {} /dev/null ; | grep -v "warn"
Просто передайте вывод через второй вызов grep
.
Ответ №2:
Чтобы найти файлы, содержащие performance
, но не warn
содержащие, перечислите файлы, содержащие performance
, затем отфильтруйте те, которые содержат warn
. Вам нужны отдельные вызовы grep
для каждого фильтра. Используйте -l
опцию для grep, чтобы она выводила только имена файлов, а не совпадающие строки. Используйте xargs
для передачи имен файлов с первого прохода в командную строку второго прохода grep
.
find /apps -type f -exec grep -l "performance" /dev/null {} |
sed 's/[[:blank:]"''']/\amp;/g' |
xargs grep -lv "warn"
( sed
Вызов в середине находится там, потому что xargs
ожидается странный формат ввода в кавычках, который не соответствует тому, что выдает любая другая команда.)
Ответ №3:
Использование -exec
опции find
команды менее эффективно, чем конвейерная передача ее в xargs
:
find /apps -print0 | xargs -0 grep -n -v "warn" | grep "performance"
Это, вероятно, также решает вашу проблему с печатью нежелательных выходных данных. Вы также, вероятно, захотите использовать -name
опцию для фильтрации определенных файлов.
find /apps -name '*.ext' -print0 | xargs -0 grep -n -v "warn" | grep "performance"
Ответ №4:
Если вы хотите найти файлы, которые вообще не содержат «warn», grep -v
это не то, что вам нужно — это выводит все строки, не содержащие «warn», но это не скажет вам, что файл (в целом) не содержит «warn»
find /apps -type f -print0 | while read -r -d '' f; do
grep -q performance "$f" amp;amp; ! grep -q warn "$f" amp;amp; echo "$f"
done