Intereting Posts

Поиск трубы в grep -v

Я пытаюсь найти все файлы определенного типа и не содержать определенную строку. Я пытаюсь сделать это, найдя трубку в grep -v

пример:

find -type f -name '*.java' | xargs grep -v "something something" 

Кажется, это не работает. Кажется, он просто возвращает все файлы, найденные командой find. Если это помогает, то, что я пытаюсь сделать, в основном найти все .java-файлы, которые соответствуют определенному имени файла (например, заканчивается на «Pb», как в SessionPb.java) и которые не имеют «extends SomethingSomething» внутри него.

Мое подозрение – новичок в unix – это то, что я делаю это неправильно. Итак, как должна выглядеть команда вместо этого?

Здесь нет необходимости в xargs . Также вам нужно использовать grep с параметром -L (файлы без соответствия), в противном случае он выведет содержимое файла вместо его имени, как в вашем примере.

 find . -type f -iname "*.java" -exec grep -L "something somethin" {} \+ 

У тебя почти все получилось …

 find . -type f -iname "*.java" -print0 | xargs -0 grep -v "something something" 

Точка. говорит, чтобы начать отсюда. (ваш подразумевает это, но никогда не предполагайте).

-iname использует поиск без учета регистра, на всякий случай (или просто в любом случае).
-print0 отправляет имена файлов в xargs с завершающим символом \ x00, что предотвращает проблемы с именами файлов, в которых есть пробелы.

'-0' на xargs говорит, что имена файлов, заканчивающиеся на \ x00, вместо возвратов.

и ваша команда grep …

Очень понравилось.


РЕДАКТИРОВАТЬ::

Из вашего обновления:

 find . -type f -iname "*pb.java" -print0 | xargs -0 grep -iL "something" 

должен помочь. (Добавлено -L от ответа @ Rush, хорошая работа)

Я понимаю, что ваш grep нуждается либо в опции -i, либо в меньшей степени.

Попробуйте выполнить команду в частях … делает ли эти данные имена файлов, которые кажутся правильными?

 find . -type f -iname "*pb.java" 

Если да, то ваша проблема, вероятно, либо ваш шаблон поиска grep не соответствует (орфографическая ошибка? Это бывает!), Либо просто нет совпадений.

Абсолютный худший случай:

 grep -riL "something" * 

будет делать БОЛЬШУЮ работу, которая ищет все, но должна дать вам некоторую отдачу.

Компьютер является компьютером: он делает то, что вы ему сказали, вместо того, что вы хотели этого сделать.

grep -v "something something" печатает все строки, которые не содержат something something . Например, он печатает две строки из следующих трех:

 hello world this is something something something else 

Чтобы распечатать файлы, которые не содержат extends SomethingSomething , используйте параметр -L :

 grep -L -E 'extends[[:space:]]+SomethingSomething' FILENAME… 

Некоторые версии grep не имеют опции -L (она не указана POSIX ). Если у вас нет, не печатайте ничего и используйте код возврата, чтобы заставить вызывающую оболочку делать то, что он должен делать.

 grep -q -E 'extends[[:space:]]+SomethingSomething' FILENAME || echo "$FILENAME" 

Кроме того, используйте awk.

 awk ' FNR == 1 && NR != 1 && !found { print fn } FNR == 1 { fn = FILENAME; found = 0; } /extends[[:space:]]+SomethingSomething/ { found = 1 } END { if (fn != "" && !found) print fn } ' 

В Linux или Cygwin (или другой системе с GNU grep) вам не нужно использовать find , поскольку grep способен рекурсировать.

 grep -R --include='*.java' -L -E 'extends[[:space:]]+SomethingSomething' 

Если ваша оболочка – ksh или bash или zsh, вы можете заставить оболочку сопоставить имя файла. В bash сначала запустите set -o globstar (вы можете поместить это в свой ~/.bashrc ).

 grep -L -E 'extends[[:space:]]+SomethingSomething' **/*.java