Як дізнатись файли в поточному каталозі, які не містять слова foo
(використовуючи grep
)?
Як дізнатись файли в поточному каталозі, які не містять слова foo
(використовуючи 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 -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
giles, які не містять рядокnew Mustache
оскільки їх все одно потрібно переписати.
Рішення
find . -iname '*.phtml' -exec grep -H -E -o -c 'new Mustache' {} \; | grep :0$ | sed 's/..$//'
Пояснення
Перед трубами:
Знайдіть
find .
Знайдіть файли рекурсивно, починаючи з цього каталогу
-iname '*.phtml'
Ім'я файлу повинно містити .phtml
(thei
робить його нечутливим до регістру)
-exec 'grep -H -E -o -c 'new Mustache' {}'
Виконайте grep
команду на кожному зі збіжених контурів
Греп
-H
Завжди друкуйте заголовки імен файлів із вихідними рядками.
-E
Інтерпретувати візерунок як розширений регулярний вираз (тобто змушувати греп поводитись як егреп).
-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
У мого грепу немає жодної опції -L. Я знаходжу рішення для досягнення цього.
Ідеї:
зробіть різницю між двома дамп-файлами за допомогою команди 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 under find, якщо вам потрібно також фільтрувати модифікований час.
Як коментує @tukan, для Ag є відкритий звіт про помилку щодо -L
/ / --files-without-matches
flag:
Оскільки у звіті про помилку є невеликий прогрес, на -L
вказану нижче опцію не слід покладатися , доки помилка не буде усунена. Використовуйте замість цього різні підходи. Посилаючись на коментар до звіту про помилку [наголос мій]:
Будь-які оновлення щодо цього?
-L
повністю ігнорує збіги в першому рядку файлу. Здається, якщо це не буде виправлено найближчим часом, прапор слід повністю видалити, оскільки він фактично не працює, як рекламується .
Як потужна альтернатива 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
-L
помилку - github.com/ggreer/the_silver_searcher/isissue/238
grep -irnw "filepath" -ve "pattern"
або
grep -ve "pattern" < file
команда вище дасть нам результат, оскільки -v знаходить зворотну сторону шуканого шаблону
-l
можливість друкувати лише ім'я файлу; але це все ще друкує імена будь-якого файлу, який містить будь-який рядок, який не містить шаблон. Я вважаю, що ОП хоче знайти файли, які не містять жодної рядки, яка містить шаблон.
Наступна команда може допомогти вам відфільтрувати рядки, що містять підрядку "foo".
cat file | grep -v "foo"
cat
.