Я пытаюсь найти все файлы определенного типа, которые не содержат определенную строку. Я пытаюсь сделать это, отправив команду find в grep -v
пример:
find -type f -name '*.java' | xargs grep -v "something something"
Это не похоже на работу. Кажется, он просто возвращает все файлы, найденные командой find. В основном я пытаюсь найти все файлы .java, которые соответствуют определенному имени файла (например, оканчивается на «Pb», как в SessionPb.java), и в которых нет «extends SomethingSomething» внутри.
Я подозреваю, что я делаю это неправильно. Так как должна выглядеть команда?
Ответы:
Здесь нет необходимости
xargs
. Кроме того , необходимо использоватьgrep
с-L
параметром (файлы без матча), вызывают в противном случае он будет выводить содержимое файла вместо его имени, как в вашем примере.источник
-L
уже есть переговоры, потому что это значитfiles _without_ match
. Поэтому вам не нужен-v
вариант здесь.find -exec \+
кто-то пишет мне, что гораздо лучше использовать xargs. почему никто не смотрит мужчину перед написанием комментария? (:-exec ... {} \+
не эквивалентноxargs
. Пожалуйста, прочтите документацию к findutils! (Я много работал над этим!)xargs
обрабатывает свои входные данные и разделяет аргументы в пустом пространстве. Кавычки также специальные (по умолчанию) дляxargs
. Ни одна из этих вещей не верна для-exec ... {} +
. Старые версииxargs
раньше считали подчеркивание индикатором EOF, но это уже не так.Вы почти поняли это ...
Точка "." говорит начать отсюда. (твое подразумевает это .. но никогда не предполагайте).
-iname использует поиск без учета регистра, на всякий случай (или просто без учета регистра).
-print0 отправляет имена файлов в xargs с последним символом \ x00, что предотвращает проблемы с именами файлов, в которых есть пробелы.
'-0' в xargs говорит, что нужно ожидать имена файлов, заканчивающиеся на \ x00, вместо возвратов.
и ваша команда grep ...
В значительной степени получил это.
РЕДАКТИРОВАТЬ::
Из вашего обновления:
должно помочь (Добавлено -L из ответа @ rush, хорошая работа)
Я понял, что вашему grep нужна либо опция -i, либо менее явный.
Попробуй команду по частям ... ДЕЙСТВИТЕЛЬНО ЛИ ВЫВОДНЫЕ имена файлов кажутся правильными?
Если это так, то, скорее всего, ваша проблема либо в том, что ваш шаблон поиска grep не соответствует (орфографическая ошибка? Это происходит!), Либо просто нет совпадений.
Абсолютный худший случай:
выполнит ОЧЕНЬ больше работы, ища все, но должно дать вам некоторый вывод.
источник
xargs -0 grep -v "something something"
вxargs -0 grep -v "something something" /dev/null
противном случае вы получите странные результаты, когда команда find не найдет подходящих файлов.Компьютер - это компьютер: он делает то, что вы сказали, а не то, что вы хотели.
grep -v "something something"
печатает все строки , которые не содержатsomething something
. Например, он печатает две строки среди следующих трех:Для печати файлов, которые
extends SomethingSomething
нигде не содержатся , используйте-L
параметр:Некоторые версии grep не имеют этой
-L
опции (она не указана в POSIX ). Если у вас нет, пусть он ничего не печатает и использует код возврата, чтобы вызывающая оболочка делала все, что должна.Или используйте awk.
На Linux или Cygwin (или другой системе с GNU grep) вам не нужно использовать
find
, так какgrep
он способен к повторению.Если ваша оболочка ksh или bash или zsh, вы можете сделать так, чтобы оболочка соответствовала имени файла. На bash запустите
set -o globstar
сначала (вы можете поместить это в свой~/.bashrc
).источник
\s
- это расширение GNU grep, которое, я думаю, является синонимом[[:space:]]
.