Как найти файлы, которые не содержат заданный шаблон строки? - PullRequest
461 голосов
/ 17 ноября 2009

Как мне найти файлы в текущем каталоге, которые не содержат слово foo (используя grep)?

Ответы [ 13 ]

735 голосов
/ 17 ноября 2009

Если ваш grep имеет опцию -L (или --files-without-match):

$ grep -L "foo" *
44 голосов
/ 09 апреля 2010

Взгляните на ack. Он автоматически делает исключение .svn, предоставляет регулярные выражения Perl и представляет собой простую загрузку одной программы Perl.

Эквивалент того, что вы ищете, должен быть в ack:

ack -L foo
15 голосов
/ 17 ноября 2009

Следующая команда дает мне все файлы, которые не содержат шаблон foo:

find .  -not  -ipath '.*svn*' -exec  grep  -H -E -o -c  "foo"  {} \; | grep 0
13 голосов
/ 17 октября 2011

Следующая команда исключает необходимость поиска, чтобы отфильтровать папки svn с помощью второй grep.

grep -rL "foo" ./* | grep -v "\.svn"
9 голосов
/ 08 апреля 2010

Вам действительно понадобится:

find .  -not  -ipath '.*svn*' -exec  grep  -H -E -o -c  "foo"  {} \; | grep :0\$
6 голосов
/ 17 декабря 2009

мне повезло с

grep -H -E -o -c "foo" */*/*.ext | grep ext:0

Мои попытки с grep -v просто дали мне все строки без "foo".

1 голос
/ 07 июня 2019

Вы можете сделать это только с помощью grep (без поиска).

grep -riL "foo" .

Это объяснение параметров, используемых на grep

     -L, --files-without-match
             each file processed.
     -R, -r, --recursive
             Recursively search subdirectories listed.

     -i, --ignore-case
             Perform case insensitive matching.

Если вы используете l (в нижнем регистре), вы получите противоположное (файлы с совпадениями)

     -l, --files-with-matches
             Only the names of files containing selected lines are written
1 голос
/ 28 марта 2019

Задача

Мне нужно провести рефакторинг большого проекта, который использует файлы .phtml для записи HTML с использованием встроенного кода PHP. Вместо этого я хочу использовать шаблоны Усы . Я хочу найти любые .phtml giles, которые не содержат строку new Mustache, так как они все еще должны быть переписаны.

Решение

find . -iname '*.phtml' -exec grep -H -E -o -c 'new Mustache' {} \; | grep :0$ | sed 's/..$//'

Объяснение

Перед трубами:

* Найти 1026 *

find . Поиск файлов рекурсивно, начиная с этого каталога

-iname '*.phtml' Имя файла должно содержать .phtml (i делает его без учета регистра)

-exec 'grep -H -E -o -c 'new Mustache' {}' Запустите команду grep на каждом из соответствующих путей

Grep

-H Всегда печатать заголовки имен файлов с выходными строками.

-E Интерпретировать шаблон как расширенное регулярное выражение (т.е. force grep вести себя как egrep).

-o Печать только соответствующей части строк.

-c В стандартный вывод записывается только количество выбранных строк.


Это даст мне список всех путей к файлам, оканчивающихся на .phtml, с указанием количества раз, которое строка new Mustache встречается в каждом из них.

$> find . -iname '*.phtml$' -exec 'grep -H -E -o -c 'new Mustache' {}'\;

./app/MyApp/Customer/View/Account/quickcodemanagestore.phtml:0
./app/MyApp/Customer/View/Account/studio.phtml:0
./app/MyApp/Customer/View/Account/orders.phtml:1
./app/MyApp/Customer/View/Account/banking.phtml:1
./app/MyApp/Customer/View/Account/applycomplete.phtml:1
./app/MyApp/Customer/View/Account/catalogue.phtml:1
./app/MyApp/Customer/View/Account/classadd.phtml:0
./app/MyApp/Customer/View/Account/orders-trade.phtml:0

Первый канал grep :0$ фильтрует этот список, чтобы включить только строки, заканчивающиеся на :0:

$> find . -iname '*.phtml' -exec grep -H -E -o -c 'new Mustache' {} \; | grep :0$

./app/MyApp/Customer/View/Account/quickcodemanagestore.phtml:0
./app/MyApp/Customer/View/Account/studio.phtml:0
./app/MyApp/Customer/View/Account/classadd.phtml:0
./app/MyApp/Customer/View/Account/orders-trade.phtml:0

Второй канал sed 's/..$//' удаляет последние два символа каждой строки, оставляя только пути к файлам.

$> find . -iname '*.phtml' -exec grep -H -E -o -c 'new Mustache' {} \; | grep :0$ | sed 's/..$//'

./app/MyApp/Customer/View/Account/quickcodemanagestore.phtml
./app/MyApp/Customer/View/Account/studio.phtml
./app/MyApp/Customer/View/Account/classadd.phtml
./app/MyApp/Customer/View/Account/orders-trade.phtml
1 голос
/ 26 июля 2018

Открыть отчет об ошибке

Как прокомментировал @tukan, есть открытый отчет об ошибке для Ag относительно флага -L / --files-without-matches:

Поскольку в сообщении об ошибке имеется небольшой прогресс, указанная ниже опция -L не следует полагаться на , пока ошибка не будет устранена. Вместо этого используйте различные подходы, представленные в этой теме. Цитирую комментарий к сообщению об ошибке [выделено мной]:

Есть ли какие-либо обновления по этому поводу? -L полностью игнорирует совпадения в первой строке файла. Похоже, если это не будет исправлено в ближайшее время, флаг должен быть полностью удален, так как он фактически не работает так, как было объявлено .


Серебряный поисковик - Ag (предполагаемая функция - см. Отчет об ошибке)

В качестве мощной альтернативы grep, вы можете использовать The Silver Searcher - Ag :

Инструмент поиска кода, похожий на ack, с акцентом на скорость.

Глядя на man ag, мы находим опцию -L или --files-without-matches:

...

OPTIONS
    ...

    -L --files-without-matches
           Only print the names of files that don´t contain matches.

То есть, рекурсивно искать файлы, которые не соответствуют foo, из текущего каталога:

ag -L foo

Для поиска в текущем каталоге файлов, которые не соответствуют foo, просто укажите --depth=0 для рекурсии:

ag -L foo --depth 0
1 голос
/ 10 ноября 2016

find *20161109* -mtime -2|grep -vwE "(TRIGGER)"

Вы можете указать фильтр в "find" и строку исключения в "grep -vwE". Используйте mtime под find, если вам нужно фильтровать и измененное время.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...