Как мне найти файлы в текущем каталоге, которые не содержат слово foo
(используя grep
)?
Как мне найти файлы в текущем каталоге, которые не содержат слово foo
(используя grep
)?
Ответы:
Если у вашего grep есть опция -L
(или --files-without-match
):
$ grep -L "foo" *
GREP_OPTIONS='--exclude-dir=.svn --exclude-dir=.git'
: ^)
-rL
вместо того, -L
чтобы сопоставлять подкаталоги
grep -L 'foo' -- *
Стандартные команды, которые используют длинные параметры, используют, --
чтобы указать, что после этого пункта больше нет параметров.
Посмотрите на ack
. Он .svn
автоматически исключает вас, предоставляет регулярные выражения Perl и представляет собой простую загрузку одной программы Perl.
Эквивалент того, что вы ищете, должен быть в ack
:
ack -L foo
Вы можете сделать это только с помощью 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
Следующая команда дает мне все файлы, которые не содержат шаблон foo
:
find . -not -ipath '.*svn*' -exec grep -H -E -o -c "foo" {} \; | grep 0
grep '0$'
файлы тоже должны быть кратны 10 строкам! Вам нужно grep ':0$'
в конце проверить наличие явного ': 0' в конце строки. Тогда вы получите только файлы с нулевыми строками.
Следующая команда исключает необходимость поиска, чтобы отфильтровать svn
папки с помощью секунды grep
.
grep -rL "foo" ./* | grep -v "\.svn"
Вам действительно нужно:
find . -not -ipath '.*svn*' -exec grep -H -E -o -c "foo" {} \; | grep :0\$
проблема
Мне нужно реорганизовать большой проект, который использует .phtml
файлы для записи HTML с использованием встроенного кода PHP. Я хочу использовать шаблоны усов вместо. Я хочу найти любые .phtml
файлы, которые не содержат строку, так new Mustache
как они все еще должны быть переписаны.
Решение
find . -iname '*.phtml' -exec grep -H -E -o -c 'new Mustache' {} \; | grep :0$ | sed 's/..$//'
объяснение
Перед трубами:
найти
find .
Поиск файлов рекурсивно, начиная с этого каталога
-iname '*.phtml'
Имя файла должно содержать .phtml
( i
делает его без учета регистра)
-exec 'grep -H -E -o -c 'new Mustache' {}'
Запустите grep
команду на каждом из подходящих путей
Grep
-H
Всегда печатайте заголовки файлов с выходными строками.
-E
Интерпретировать шаблон как расширенное регулярное выражение (то есть заставить 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
У моего grep нет опции -L. Я нахожу обходной путь для достижения этой цели.
Идеи:
сделайте разницу между файлом 2 dump командой diff.
grep 'foo' *.log | cut -c1-14 | uniq > txt1.txt
grep * *.log | cut -c1-14 | uniq > txt2.txt
diff txt1.txt txt2.txt | grep ">"
diff
между двумя выходными потоками (я думаю, что вы окружаете команды круглыми скобками, и где-то тоже есть угловая скобка), если ваши системы поддерживают это, что, я думаю, вопрос, так как он не поддерживаетgrep -L
find *20161109* -mtime -2|grep -vwE "(TRIGGER)"
Вы можете указать фильтр в «find» и строку исключения в «grep -vwE». Используйте mtime в find, если вам нужно фильтровать и измененное время.
Как прокомментировал @tukan, есть открытый отчет об ошибке для Ag относительно флага -L
/ --files-without-matches
:
Поскольку в отчете об ошибках имеется небольшой прогресс, на -L
указанную ниже опцию не следует полагаться , пока ошибка не будет устранена. Вместо этого используйте различные подходы, представленные в этой теме. Цитирую комментарий к сообщению об ошибке [выделено мной]:
Есть какие-нибудь обновления по этому поводу?
-L
полностью игнорирует совпадения в первой строке файла. Похоже, если это не будет исправлено в ближайшее время, флаг должен быть полностью удален, так как он фактически не работает так, как рекламируется вообще .
В качестве мощной альтернативы grep
вы можете использовать Серебряный Искатель - 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
-L
ошибки - github.com/ggreer/the_silver_searcher/issues/238
grep -irnw "filepath" -ve "pattern"
или
grep -ve "pattern" < file
Команда выше даст нам результат, так как -v находит инверсию искомого шаблона
-l
опцию, чтобы напечатать только имя файла; но это все еще печатает имена любого файла, который содержит любую строку, которая не содержит образец. Я полагаю, что ОП хочет найти файлы, которые не содержат строки, содержащей шаблон.
Следующая команда может помочь вам отфильтровать строки, содержащие подстроку "foo".
cat file | grep -v "foo"
cat
.