Suchen von Dateien, die einen bestimmten String enthalten, mit find (1) und grep (1)

70

find . -type f -print -exec cat {} \; | grep some string

Der obige Befehl gibt den Dateipfad nicht aus.

Ich verwende: Ubuntu, bash 4.

H. Rabiee
quelle
Möglicherweise werden die erwarteten Ergebnisse aufgrund des Grep-Filters nicht erreicht. Was ist damit:find . -type f -fprint /dev/stderr -exec cat {} \; | grep some string
artistoex
Was ist das Ziel, das Sie erreichen wollen? Bei der Ausgabe werden Zeichenfolgen aus Dateien abgerufen. Möchten Sie den Pfad dieser Dateien ermitteln?
Mirkobrankovic
Ja, ich möchte den Pfad der Dateien drucken, die die Zeichenfolge 'some string' enthalten. @artistoex Vorschlag druckt alle Dateipfade.
H. Rabiee
Möglicherweise möchten Sie einfach ackalle Dateien im aktuellen Verzeichnis durchsuchen und möglicherweise nur bestimmte Dateitypen filtern.
Jaap Eldering

Antworten:

87

Das liegt daran, dass Sie grepeinen Textstrom einspeisen, der zufällig Dateinamen enthält. Da Sie keine Dateinamen als Argumente für grep angegeben haben, kann nicht davon ausgegangen werden, aus welcher Datei eine übereinstimmende Zeile stammt. Verwendung xargs:

find . -type f -print | xargs grep "some string"

Da Sie GNU find / xargs haben, ist dies eine sicherere Möglichkeit für xargs, Dateinamen zu lesen:

find . -type f -print0 | xargs -0 grep "some string"

Wenn Sie nur die Dateinamen möchten, die eine übereinstimmende Zeile haben, ohne die übereinstimmende Zeile anzuzeigen:

find . -type f -print0 | xargs -0 grep -l "some string"
Glenn Jackman
quelle
Wie würde ich die obigen Befehle mit Suchen & Ersetzen kombinieren? Wie in, grep dann sed?
CMCDragonkai
1
Die find | grep-Pipeline gibt Dateinamen aus, also:sed '...' $(find ... | xargs grep -l ...)
glenn jackman
107

ich benutze

grep "some string" . -R

und es funktioniert schneller

ps

Komplexerer Anwendungsfall

grep -HiRE "some string|other string" . #H for file printing, i for case-insensitive, R for recursive search, E for regex 

Parametererklärung lesen

grep --help | grep -- -i
ArcherGodson
quelle
17
Und -nwenn Sie Zeilennummern wollen. +1 für eine vereinfachte Antwort.
Chad Skeeters
@ChadSkeeters genau. Die Verwendung des Fund gibt keine solche Lösung.
ArcherGodson
1
Dies sollte als die richtige Antwort markiert werden, um ehrlich zu sein. Die aktuell ausgewählte Option beschreibt etwas ganz anderes.
12

Ich suche oft nach Quellcode in komplexen Ordnerstrukturen und finde es nützlich, wenn ich:

cd /your/folder/
grep -rHino "your string"

Mit diesen Parametern erhalte ich ohne Verwendung von find den vollständigen Pfad der Datei und die Zeilennummer , die die angegebene Zeichenfolge enthält .

Es ist auch einfach , weil es sich zu erinnern BASH es durch Ihre Suche wie ein rhino :)

Ich werde anhand eines kurzen Beispiels zeigen, wie das funktioniert.

Lassen Sie uns den Inhalt einer Datei mit cat anzeigen:

jeeves ~ # cat fw.stop
#!/bin/sh
echo "Stopping firewall and allowing everyone..."
iptables -F
iptables -X
iptables -t nat -F
iptables -t nat -X
iptables -t mangle -F
iptables -t mangle -X
iptables -P INPUT ACCEPT
iptables -P FORWARD ACCEPT
iptables -P OUTPUT ACCEPT

Und lassen Sie uns rekursiv nach allen Dateien suchen, die den String "iptables -P" enthalten:

jeeves ~ # grep -rinHo "iptables -P"
fw.stop:9:iptables -P
fw.stop:10:iptables -P
fw.stop:11:iptables -P

Wie Sie in der Ausgabe sehen können, haben wir Dateiname: Trefferzeile: gesuchte Zeichenfolge

Hier ist eine detailliertere Beschreibung der verwendeten Parameter:

-r Liest und verarbeitet rekursiv für jeden Verzeichnisoperanden alle Dateien in diesem Verzeichnis. Befolgen Sie symbolische Links in der Befehlszeile, überspringen Sie jedoch Symlinks, die rekursiv auftreten. Beachten Sie, dass grep das Arbeitsverzeichnis durchsucht, wenn kein Dateioperand angegeben wird. Dies entspricht der Option '--directories = recurse'.

-i Gibt den Dateinamen für jede Übereinstimmung aus. Dies ist die Standardeinstellung, wenn mehr als eine Datei durchsucht werden muss.

-n Stellt jeder Ausgabezeile die 1-basierte Zeilennummer in der Eingabedatei voran. (-n wird von POSIX angegeben.)

-H Gibt den Dateinamen für jede Übereinstimmung aus. Dies ist die Standardeinstellung, wenn mehr als eine Datei durchsucht werden muss.

-o Nur die übereinstimmenden (nicht leeren) Teile der übereinstimmenden Zeilen ausgeben, wobei sich jeder dieser Teile in einer separaten Ausgabezeile befindet. Ausgabezeilen verwenden dieselben Begrenzer wie Eingabe, und Begrenzer sind Nullbytes, wenn auch -z (--null-data) verwendet wird (siehe Andere Optionen).

Pitto
quelle
2

Ich bevorzugte

| Suchen Sie die Datei | make grep ont finding file | Den vollständigen Pfad der Datei anzeigen

find / -type f -exec grep 'irgendein String' {} \; -exec echo {} \;

user515185
quelle
0

Silver Searcher ist eine sehr schnelle und praktische Anwendung, um nach Dateien und Inhalten zu suchen.

Um Ihr Problem zu lösen, würde der Befehl silver searcher so aussehen ...

ag 'some string' -l

-l Nur Dateinamen drucken, die Übereinstimmungen enthalten (die übereinstimmenden Zeilen nicht drucken)

qoomon
quelle