2010-11-25 2 views
18

Wie kann ich Grep in Cygwin verwenden, um alle Dateien zu finden, die BOTH Worte enthalten.Grep Suche alle Dateien im Verzeichnis nach String1 UND String2

Dies ist, was ich verwende, um alle Dateien in einem Verzeichnis für ein Wort rekursiv suchen:

grep -r "db-connect.php" . 

Wie kann ich die oben zu suchen Dateien erweitern, die enthalten sowohl „db-connect.php“ AND " Ausführung".

Ich versuchte dies: grep -r "db-connect.php\|version" ., aber das ist ein OR, d. H. Es wird Datei, die das eine oder andere enthalten.

Dank alle für jede Hilfe

+0

Sie nur zwei greps tun könnte. Eins für ein Wort und eins für das andere und dann finden Sie die Schnittmenge der passenden Dateien. Es ist nicht * so * trivial, aber ich weiß nicht, ob es einen besseren Weg gibt, es zu tun. –

Antwort

20
grep -r db-connect.php . | grep version 
+0

Brilliant, danke. Dateien zurückgegeben scheint weniger als ich erwartet hatte. Untersuchung ... – Abs

+0

Ok, es funktioniert! – Abs

+11

nicht diese Fälle vermissen, wo sie beide in der Datei sind, aber auf verschiedenen Linien? – lathomas64

3

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

Ich habe es nicht im rekursiven Modus versucht, aber es sollte das gleiche sein.

+0

Das gibt keine Dateien zurück, in denen sich beide Zeichenfolgen befinden, es gibt sie für das eine oder das andere zurück. Recht? – Abs

+1

Nun, nein, es sollte alle Dateien zurückgeben, die die zwei Zeichenfolgen enthalten (die Zeichenfolgen befinden sich in unterschiedlichen Zeilen). Versuchen Sie: grep "db-connect.php" * | Schnitt -d: -f1 | xargs grep "Version" | cut -f1 -d: nur die Dateinamen haben ... – jzrk

+0

Dieser letzte Befehl ist nützlich, half mir, die Dateien zu überprüfen, die ich überprüfen musste. Also vielen Dank. +1. – Abs

1

Meinst du "string1" und "string2" in derselben Zeile?

grep 'string1.*string2' 

Auf derselben Zeile, aber in unbestimmter Reihenfolge?

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

Oder beide Strings müssen irgendwo in der Datei erscheinen?

grep -e string1 -e string2 
+1

Das letzte ist das gleiche wie 'grep 'string1 \ | string2 "und ist ein' OR' nicht ein 'AND'. –

1

Das nutzt PCRE (Perl-Compatible Regular Expressions) mit mehrzeiligen Anpassung und gibt die Dateinamen der Dateien, die beide Zeichenketten enthalten (AND statt OR).

grep -Plr '(?m)db-connect\.php(.*\n)*version|version(.*\n)*db-connect\.php' . 
3

Um and zusammen mehrere Suchen, verwenden Sie mehrere Behauptungen Look-Ahead, eine pro Sache für abgesehen sah von dem zuletzt:

statt schreiben

grep -P A * | grep B 

Sie

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

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

Nicht schreiben

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

, weil das nicht auf Überschneidungen, während die (?=…)(?=…) Technik nicht der Fall ist.

Sie können auch in NOT Operatoren hinzufügen. Um nach Zeilen zu suchen, die nicht mit X übereinstimmen, verwenden Sie normalerweise -v in der Befehlszeile. Aber Sie können das nicht tun, wenn es Teil eines größeren Musters ist. Wenn dies der Fall ist, fügen Sie dem Muster (?=(?!X).)*$) hinzu, um irgendetwas mit X darin auszuschließen.

Also stellen Sie sich vor, Sie wollen Linien mit allen drei von A, B und dann entweder von C oder D, aber, die nicht X oder Y in ihnen haben übereinstimmen.Alles, was Sie brauchen, ist dies:

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

In einigen Shells und in einigen Einstellungen. Du musst der ! entkommen, wenn es dein history-substitution Charakter ist.

Dort, ist das nicht ziemlich cool?

3

In meinem cygwin den Antworten hat nicht funktioniert, aber die folgenden haben:

grep -l firststring `grep -r -l secondstring . ` 
4

Wenn Sie mehrere Zeichenfolgen in einer Datei mit grep, die unterschiedliche Linien haben, verwenden Sie den folgenden Befehl ein:

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

Dadurch erhalten Sie eine Liste der Dateien, die expr1, expr2 und expr3 enthalten.

Beachten Sie, dass diese Dateien Fehler verursachen, wenn einer der Dateinamen in dem Verzeichnis Leerzeichen enthält. Dies kann behoben werden, indem -0 hinzugefügt wird, denke ich an grep und xargs.

+0

Um Null-Trennzeichen zu verwenden, um Dateinamen mit Leerzeichen zu behandeln: 'grep -rl -Z expr1 | xargs -0 grep -l -Z expr2 | xargs -0 grep -Z -l expr3'. –

0

Warum nur grep bleiben:

perl -lne 'print if(/db-connect.php/&/version/)' *