Grep Искать все файлы в каталоге для string1 AND string2

18

Как я могу использовать grep в cygwin для поиска всех файлов, содержащих слова BOTH .

Это то, что я использую для поиска всех файлов в каталоге рекурсивно для одного слова:

grep -r "db-connect.php" .

Как я могу расширить это, чтобы искать файлы, содержащие как «db-connect.php», так и «версию».

Я пробовал это: grep -r "db-connect.php\|version" . , но это OR, то есть он получает файл, который содержит тот или иной.

Спасибо всем за помощь

    
задан Abs 25.11.2010 в 11:14
источник
  • Вы могли бы просто сделать два greps. Один для одного слова и один для другого, а затем найти пересечение согласованных файлов. Это не так тривиально, но я не знаю, есть ли лучший способ сделать это. –  Noufal Ibrahim 25.11.2010 в 11:19

8 ответов

20
grep -r db-connect.php . | grep version
    
ответ дан marcog 25.11.2010 в 11:17
  • Блестяще, спасибо. Возвращенные файлы кажутся меньше, чем я ожидал. Исследуя ... –  Abs 25.11.2010 в 11:30
  • Хорошо, это работает! –  Abs 25.11.2010 в 11:42
  • не эти случаи, когда они оба находятся в файле, но на разных строках? –  lathomas64 10.06.2011 в 17:36
  • Да, это будет, @ lathomas64. –  Weston Odom 05.06.2015 в 18:53
4

Если вы хотите grep для нескольких строк в файле с разными строками, используйте следующую команду:

grep -rl expr1 | xargs grep -l expr2 | xargs grep -l expr3

Это даст вам список файлов, содержащих expr1, expr2 и expr3.

Обратите внимание, что если любое из имен файлов в каталоге содержит пробелы, эти файлы будут вызывать ошибки. Это можно исправить добавлением -0, я думаю, для grep и xargs.

    
ответ дан Coroos 01.08.2013 в 13:44
  • Чтобы использовать нулевые ограничители для обработки имен файлов с пробельными символами: grep -rl -Z expr1 | xargs -0 grep -l -Z expr2 | xargs -0 grep -Z -l expr3. –  Dennis Williamson 18.01.2014 в 21:32
3

grep "db-connect.php" * | cut -d: -f1 | xargs grep "version"

Я не пробовал его в рекурсивном режиме, но он должен быть тем же.

    
ответ дан jzrk 25.11.2010 в 11:29
  • Это не возвращает файлы, в которых находятся обе строки, и возвращает их для одного или другого. Правильно? –  Abs 25.11.2010 в 11:32
  • Ну, нет, он должен возвращать все файлы, содержащие две строки (строки thoses находятся на разных строках). Попробуйте: grep "db-connect.php" * | cut -d: -f1 | xargs grep "версия" | cut -f1 -d: иметь только имена файлов ... –  jzrk 25.11.2010 в 11:36
  • Эта последняя команда полезна, помогла подтвердить файлы, которые мне нужно было проверить. Так что спасибо тебе. +1. –  Abs 25.11.2010 в 11:44
  • имел аналогичный случай, и это сработало отлично, за исключением случаев, когда первый grep только вернул 1 файл, а затем не получил имя файла из xargs grep только 2-й строки –  lathomas64 10.06.2011 в 17:37
3

В and вместе с несколькими поисковыми запросами используйте несколько утверждений с просмотром, по одному на предмет, который был найден отдельно от последнего:

вместо записи

grep -P A  * | grep B

вы пишете

grep -P '(?=.*A)B' *

grep -Pr '(?=.*db-connect\.php)version' .

Не пишите

grep -P 'A.*B|B.*A' *

, потому что это не выполняется при перекрытиях, тогда как метод (?=…)(?=…) не работает.

Вы также можете добавить в NOT операторов. Для поиска строк, которые не соответствуют X , вы обычно, конечно, используете -v в командной строке. Но вы не можете этого сделать, если это часть более крупного шаблона. Когда это произойдет, вы добавите (?=(?!X).)*$) к шаблону, чтобы исключить что-либо с X в нем.

Итак, представьте, что вы хотите совместить строки со всеми тремя из A, B, а затем с C или D, , но , которые не имеют X или Y в них. Все, что вам нужно, это:

grep -P '(?=^.*A)(?=^.*B)(?=^(?:(?!X).)*$)(?=^(?:(?!Y).)*$)C|D' *

В некоторых оболочках и в некоторых настройках. вам придется избегать ! , если это ваш символ замены истории.

Там, не так ли круто?

    
ответ дан tchrist 26.11.2010 в 21:56
3

В моем кигвине данные ответы не сработали, но следующее:

grep -l firststring 'grep -r -l secondstring . '
    
ответ дан incircuitous 31.07.2013 в 23:56
1

Вы имеете в виду «string1» и «string2» в одной строке?

grep 'string1.*string2'

В той же строке, но в неопределенном порядке?

grep '(string1.*string2)|(string2.*string1)'

Или обе строки должны появляться в файле где угодно?

grep -e string1 -e string2
    
ответ дан glenn jackman 25.11.2010 в 19:40
  • Этот последний является тем же самым, что и grep 'string1 \ | string2' и является OR, а не AND. –  Dennis Williamson 26.11.2010 в 21:16
1

Использует PCRE (регулярные выражения, совместимые с Perl) с многострочным совпадением и возвращает имена файлов, которые содержат обе строки ( AND , а не OR ).

grep -Plr '(?m)db-connect\.php(.*\n)*version|version(.*\n)*db-connect\.php' .
    
ответ дан Dennis Williamson 26.11.2010 в 21:33
0

Зачем придерживаться только grep:

perl -lne 'print if(/db-connect.php/&/version/)' *
    
ответ дан Vijay 01.08.2013 в 13:49