Как использовать grep, чтобы найти все файлы, которые содержат один шаблон, но не имеют второго? - PullRequest
5 голосов
/ 14 сентября 2009

Есть ли простой способ использования grep (или в сочетании с другими стандартными инструментами командной строки) для получения списка всех файлов, которые содержат один шаблон, но не имеют второго шаблона?

В моем конкретном случае я хочу список всех файлов, которые содержат шаблон:

override.*commitProperties

пока не содержит:

super.commitProperties

Я на Windows, но широко использую Cygwin. Я знаю, как найти все файлы с первым шаблоном ИЛИ все шаблоны без второго, но я не уверен, как объединить эти запросы.

Я бы предпочел ответы, которые являются общими, так как у меня есть чувство, что многие другие люди могут найти этот тип запроса полезным. Мне достаточно легко принять общее решение и включить мои ценности. Я просто включил свой конкретный пример, чтобы облегчить объяснение.

Ответы [ 6 ]

10 голосов
/ 14 сентября 2009
grep -rl "override.*commitProperties" . | xargs grep -L "super.commitProperties"

-l печатает файлы с совпадением

-L печатает файлы без совпадения

4 голосов
/ 14 сентября 2009

Попробуйте

find . -print0 | xargs -0 grep -l "override.*commitProperties" \
| tr '\012' '\000' | xargs -0 grep -L super.commitProperties

Команда tr преобразует новые строки в ascii null, так что вы можете использовать -0 во втором xargs, избегая всех проблем с пробелами в именах файлов и т. Д.

Результат теста:

/tmp/test>more 1 2 3 | cat
::::::::::::::
1
::::::::::::::
override.*commitProperties
super.commitProperties
::::::::::::::
2
::::::::::::::
override.*commitProperties
::::::::::::::
3
::::::::::::::
hello world
/tmp/test>find . -print0 | xargs -0 grep -l "override.*commitProperties" | tr '\012' '\000' | xargs -0 grep -L super.commitProperties
./2
/tmp/test>

Как отметил Дуглас, find + xargs можно заменить на grep -r.

2 голосов
/ 20 сентября 2009

Мое решение похоже на решение Дугласа Лидера, за исключением того, что я не использую xargs:

grep -l 'override.*commitProperties' $(grep -L super.commitProperties *.txt)

Команда grep -L создает список файлов, которые НЕ содержат шаблон super.commitProperties , команда grep -l ищет * переопределить. commitProperties шаблон из этого списка.

В целом, это другой способ снять кожу с кошки.

2 голосов
/ 14 сентября 2009

Используйте комбинацию из 2 greps и comm, как показано ниже (модели A и B). Обратите внимание, что конвейерный grep не будет работать, так как шаблоны могут быть на разных линиях.

$ cat a
A
$ cat b
B
$ cat ab
A
B

$ grep -l A * > A.only
$ grep -l B * > B.only  

$ comm -23 A.only B.only 
a

ПРИМЕЧАНИЕ. Команда comm выводит строки, общие или уникальные для двух файлов. «-23» печатает строки, уникальные для первого файла, таким образом подавляя имена файлов во втором файле.

1 голос
/ 02 июля 2010

ack -l --make "override.*commitProperties" | xargs ack -L "super.commitProperties"

Я использовал эту тему и пытался сделать рекурсивный поиск. Это заняло 25 минут +, поэтому выяснилось около ack. Сделал это за 5 минут.

Удобный инструмент ack.

0 голосов
/ 28 ноября 2014
    grep "override.*commitProperties" *| grep -v "super.commitProperties" | cut -d":" -f1
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...