Wie finde ich alle Dateien, die bestimmten Text enthalten, unter Linux?

5258

Ich versuche einen Weg zu finden, mein gesamtes Linux-System nach allen Dateien zu durchsuchen, die eine bestimmte Textzeichenfolge enthalten. Zur Verdeutlichung suche ich nach Text in der Datei, nicht im Dateinamen.

Als ich nachgeschlagen habe, wie das geht, bin ich zweimal auf diese Lösung gestoßen:

find / -type f -exec grep -H 'text-to-find-here' {} \;

Es funktioniert jedoch nicht. Es scheint jede einzelne Datei im System anzuzeigen.

Ist dies nahe an der richtigen Vorgehensweise? Wenn nicht, wie soll ich? Diese Fähigkeit, Textzeichenfolgen in Dateien zu finden, wäre für einige Programmierprojekte, die ich mache, außerordentlich nützlich.

Nathan
quelle
21
Denken Sie daran, dass grep .unter anderem jeden als Platzhalter mit einem Zeichen interpretiert . Mein Rat ist, immer entweder fgrep oder egrep zu verwenden.
Walter Tross
10
Jedenfalls warst du fast da! Ersetzen Sie einfach -Hmit -l(und vielleicht auch grepmit fgrep). Um Dateien mit bestimmten Namensmustern auszuschließen, würden Sie diese findauf fortgeschrittenere Weise verwenden. Es lohnt sich jedoch zu lernen, wie man es benutzt find. Einfach man find.
Walter Tross
6
find … -exec <cmd> +ist einfacher zu tippen und schneller als find … -exec <cmd> \;. Dies funktioniert nur, wenn <cmd>eine beliebige Anzahl von Dateinamenargumenten akzeptiert wird. Die Einsparung an Ausführungszeit ist besonders groß, wenn <cmd>der Start wie bei Python- oder Ruby-Skripten langsam ist.
Hagello
Um in einem bestimmten Pfad nicht rekursiv zu suchen, lautet der Befehl `grep --include = *. Txt -snw" pattern "thepath / *.
Stéphane Laurent
@ StéphaneLaurent Ich denke, Sie erschweren es zu sehr. Sagen grep "pattern" path/*.txt
Sie

Antworten:

9520

Mach Folgendes:

grep -rnw '/path/to/somewhere/' -e 'pattern'
  • -roder -Rist rekursiv,
  • -n ist die Zeilennummer und
  • -w steht für Match das ganze Wort.
  • -l (Kleinbuchstabe L) kann hinzugefügt werden, um nur den Dateinamen der übereinstimmenden Dateien anzugeben.

Zusammen mit diesen --exclude, --include, --exclude-dirkönnten Flaggen für die effiziente Suche verwendet werden:

  • Dadurch werden nur die Dateien durchsucht, die die Erweiterungen .c oder .h haben:

    grep --include=\*.{c,h} -rnw '/path/to/somewhere/' -e "pattern"
    
  • Dies schließt die Suche nach allen Dateien aus, die mit der Erweiterung .o enden:

    grep --exclude=*.o -rnw '/path/to/somewhere/' -e "pattern"
    
  • Bei Verzeichnissen ist es möglich, ein bestimmtes Verzeichnis (bestimmte Verzeichnisse) über --exclude-dirParameter auszuschließen . Dies schließt beispielsweise die Verzeichnisse dir1 /, dir2 / und alle aus, die mit * .dst /: übereinstimmen.

    grep --exclude-dir={dir1,dir2,*.dst} -rnw '/path/to/somewhere/' -e "pattern"
    

Dies funktioniert sehr gut für mich, um fast den gleichen Zweck wie Ihren zu erreichen.

Weitere Optionen finden Sie unter man grep.

rakib_
quelle
74
benutze --exclude. wie "grep -rnw --exclude = *. o 'Verzeichnis' -e" Muster "
rakib_
98
Es ist erwähnenswert: Es scheint, dass die rOption faul ist (zuerst die Tiefe durchläuft, dann nach dem ersten Verzeichnis stoppt), während sie Rgierig ist (den gesamten Baum korrekt durchläuft).
Eliran Malka
5
grep -rnw "String, nach dem ich gesucht habe" hat getan, was ich brauchte. Vielen Dank!
ViliusK
33
Hinweis (insbesondere für Neulinge): Die Anführungszeichen im obigen Befehl sind wichtig.
madD7
69
@Eliran Malka Ren rdurchläuft beide Verzeichnisse korrekt, Rfolgt jedoch symbolischen Links.
Bzeaman
1499

Sie können verwenden grep -ilR:

grep -Ril "text-to-find-here" /
  • i steht für Ignorieren der Groß- / Kleinschreibung (in Ihrem Fall optional).
  • R steht für rekursiv.
  • l steht für "zeige den Dateinamen, nicht das Ergebnis selbst".
  • / steht für das Starten an der Wurzel Ihrer Maschine.
fedorqui 'SO hör auf zu schaden'
quelle
85
Aufgrund meiner Erfahrung -iverlangsamt sich das sehr, also benutze es nicht, wenn es nicht nötig ist. Testen Sie es in einem bestimmten Verzeichnis und verallgemeinern Sie es dann. Es sollte innerhalb weniger Minuten abgeschlossen sein. Ich denke, ein regulärer Ausdruck würde es langsamer machen. Aber meine Kommentare basieren auf Vermutungen. Ich empfehle Ihnen, sie timevor der Leitung zu testen .
Fedorqui 'SO hör auf,'
4
Ja, /*steht dafür. Jedenfalls habe ich es gerade getestet und festgestellt, dass es einfach /funktioniert.
Fedorqui 'SO hör auf zu schaden'
10
Wenn Sie nicht mit einem regulären Ausdruck suchen, können Sie auf den meisten Systemen fgrep anstelle von grep verwenden.
Markle976
8
Ja @ markle976, in der Tat von man grep : fgrep is the same as grep -F -> Interpret PATTERN as a list of fixed strings.
Fedorqui 'SO hör auf,'
17
Sie können / durch den Pfad zum Verzeichnis ersetzen grep -Ril "text-to-find-here" ~/sites/oder verwenden. für aktuelles Verzeichnisgrep -Ril "text-to-find-here" .
Schwarz
329

Sie können ack verwenden . Es ist wie grep für Quellcode. Sie können damit Ihr gesamtes Dateisystem scannen.

Mach einfach:

ack 'text-to-find-here'

In Ihrem Stammverzeichnis.

Sie können auch reguläre Ausdrücke verwenden , den Dateityp angeben usw.


AKTUALISIEREN

Ich habe gerade The Silver Searcher entdeckt , das wie ack ist, aber 3-5x schneller als es und sogar Muster aus einer .gitignoreDatei ignoriert .

Stephan
quelle
57
Sehr nützlich, einfach und schnell. Warnung: "In von Debian abgeleiteten Distributionen wird ack als" ack-grep "verpackt, da" ack "bereits vorhanden war" (von beyondgrep.com/install ). Sie können einen Kanji-Code-Konverter unter diesen Linuxes ausführen ...
Jose_GD
11
ack oder ack-grep hat schöne Highlights, aber find + grep bei richtiger Verwendung ist viel besser in der Leistung
Sławomir Lenart
14
Beachten Sie, dass ripgrep schneller ist als alles andere, was hier erwähnt wird, einschließlich The Silver Searcher und plain 'ol grep. Siehe diesen Blog-Beitrag zum Beweis.
Radon Rosborough
194

Sie können verwenden:

grep -r "string to be searched"  /path/to/dir

Das rsteht für rekursiv und sucht daher im angegebenen Pfad und auch in seinen Unterverzeichnissen. Hier erfahren Sie den Dateinamen und können die Zeile in der Datei ausdrucken, in der die Zeichenfolge angezeigt wird.

Oder ein Befehl ähnlich dem, den Sie versuchen (Beispiel :) zum Suchen in allen Javascript-Dateien (* .js):

find . -name '*.js' -exec grep -i 'string to search for' {} \; -print

Dadurch werden die Zeilen in den Dateien gedruckt, in denen der Text angezeigt wird, der Dateiname wird jedoch nicht gedruckt.

Zusätzlich zu diesem Befehl können wir auch Folgendes schreiben: grep -rn "Zu durchsuchender String" / path / to / directory / oder / file -r: rekursive Suche n: Zeilennummer wird für Übereinstimmungen angezeigt

learner_19
quelle
1
Vielen Dank für die Find-Version. Meine grep-Version (Busybox für NAS) hat nicht die Option -r, ich brauchte wirklich eine andere Lösung!
JC
3
Vielen Dank für die 'find'-Version! Es ist so wichtig, nach ' .js' oder ' .txt' usw. filtern zu können . Niemand möchte stundenlang darauf warten, dass grep alle Multi-Gigabyte-Videos aus dem letzten Familienurlaub durchsucht, selbst wenn der Befehl lautet einfacher zu tippen.
Mightypile
Besser grep als akzeptierte Version, weil akzeptiert nicht halbe Wörter suchen
waza123
114

Sie können dies verwenden:

grep -inr "Text" folder/to/be/searched/
AR
quelle
12
am einfachsten, ausführlich, rekursiv und ohne Berücksichtigung der Groß- und Kleinschreibung. Daumen hoch.
Francesco Casula
Wenn Sie -A3 hinzufügen, ist es noch besser
Albanx
73

Liste der Dateinamen, die einen bestimmten Text enthalten

Zunächst einmal, ich glaube , Sie verwendet haben , -Hstatt -l. Sie können auch versuchen, den Text in Anführungszeichen einzufügen, gefolgt von {} \.

find / -type f -exec grep -l "text-to-find-here" {} \; 

Beispiel

Angenommen, Sie suchen in Ihrem Verzeichnis nach Dateien mit dem spezifischen Text "Apache License". Es werden ähnliche Ergebnisse wie unten angezeigt (die Ausgabe hängt vom Inhalt Ihres Verzeichnisses ab).

bash-4.1$ find . -type f -exec grep -l "Apache License" {} \; 
./net/java/jvnet-parent/5/jvnet-parent-5.pom
./commons-cli/commons-cli/1.3.1/commons-cli-1.3.1.pom
./io/swagger/swagger-project/1.5.10/swagger-project-1.5.10.pom
./io/netty/netty-transport/4.1.7.Final/netty-transport-4.1.7.Final.pom
./commons-codec/commons-codec/1.9/commons-codec-1.9.pom
./commons-io/commons-io/2.4/commons-io-2.4.pom
bash-4.1$ 

Entfernen Sie die Empfindlichkeit des Gehäuses

Auch wenn Sie den Fall nicht wie "Text" oder "TEXT" verwenden, können Sie den -iSchalter verwenden, um den Fall zu ignorieren. Weitere Details können Sie hier lesen .

Hoffe das hilft dir.

lkamal
quelle
2
Was dieser Befehl tut: findÜbergibt alle gefundenen Pfade an den Befehl grep -l "text-to-find-here" <file found>". Sie können dem Dateinamen Einschränkungen hinzufügen, z. B. find / -iname "*.txt"um nur in Dateien zu suchen, deren Name auf.txt
Mene
1
@Auxiliary - enthält eine Beispielausgabe, um Verwirrung für die Leser zu vermeiden.
lkamal
2
@Mene Es ist ein wirklich trauriger Zustand, dass der Kommentar von Auxiliary mehr Stimmen hat als der Ihre ... selbst wenn ihr Kommentar aus dem Jahr 2014 stammt und Ihr Kommentar 2017 ist, hat ihr Kommentar 6, wenn er genau 0 haben sollte und Ihr Kommentar nur einen (jetzt zwei) isn hat Das würde ich nicht glauben.
Pryftan
@Mene Davon abgesehen -inamewird die Groß- und Kleinschreibung nicht berücksichtigt, was bedeutet, dass beispielsweise auch .TXT-Dateien sowie TxT und TXt usw. gefunden werden.
Pryftan
66

grep( GNU oder BSD )

Mit dem grepTool können Sie den aktuellen Ordner rekursiv durchsuchen, z.

grep -r "class foo" .

Hinweis: -r- Unterverzeichnisse rekursiv durchsuchen.

Sie können auch die Globbing-Syntax verwenden, um in bestimmten Dateien zu suchen, z.

grep "class foo" **/*.c

Hinweis: Mit der Globbing-Option ( **) werden alle Dateien rekursiv mit einer bestimmten Erweiterung oder einem bestimmten Muster gescannt. Führen Sie Folgendes aus, um diese Syntax zu aktivieren : shopt -s globstar. Sie können auch **/*.*für alle Dateien (außer versteckte und ohne Erweiterung) oder andere Muster verwenden.

Wenn Sie den Fehler haben, dass Ihr Argument zu lang ist, sollten Sie Ihre Suche eingrenzen oder findstattdessen die folgende Syntax verwenden:

find . -name "*.php" -execdir grep -nH --color=auto foo {} ';'

Alternativ verwenden ripgrep.

ripgrep

Wenn Sie an größeren Projekten oder großen Dateien arbeiten, sollten Sie ripgrepstattdessen Folgendes verwenden:

rg "class foo" .

Überprüfen Sie die Dokumente, Installationsschritte oder den Quellcode auf der GitHub-Projektseite .

Es ist viel schneller als jedes anderes Tool wie GNU / BSD grep , ucg, ag, sift, ack, ptoder ähnlich, da es auf der Spitze gebaut Rust Regex - Engine , die endlichen Automaten verwendet, SIMD und aggressive wörtliche Optimierungen sehr schnell zu machen suchen.

Es unterstützt Ignoriermuster, die in .gitignoreDateien angegeben sind, sodass ein einzelner Dateipfad mit mehreren Glob-Mustern gleichzeitig abgeglichen werden kann.


Sie können die allgemeinen Parameter verwenden, z.

  • -i - Unempfindliche Suche.
  • -I - Ignorieren Sie die Binärdateien.
  • -w - Suche nach den ganzen Wörtern (im Gegensatz zur teilweisen Wortübereinstimmung).
  • -n - Zeigen Sie die Linie Ihres Spiels.
  • -C/ --context(zB -C5) - Erhöht den Kontext, sodass Sie den umgebenden Code sehen.
  • --color=auto - Markieren Sie den passenden Text.
  • -H - Zeigt den Dateinamen an, in dem sich der Text befindet.
  • -c- Zeigt die Anzahl der übereinstimmenden Zeilen an. Kann mit kombiniert werden -H.
Kenorb
quelle
1
Ich finde auch erweitertes Globbing nützlich. Beachten Sie jedoch, dass bei einer wirklich großen Anzahl von Dateien der Fehler "Argumentliste zu lang" angezeigt werden kann. (Einfaches Globbing ist auch anfällig für diese Art von Fehlern).
Yoory N.
2
Für das Inhalieren eines ganzen Dateisystems ist rg weitaus weniger schmerzhaft als fast jedes andere Tool.
lk
55

Wenn Ihr grepnicht rekursive Suche nicht unterstützt, können Sie kombinieren findmit xargs:

find / -type f | xargs grep 'text-to-find-here'

Ich finde das leichter zu merken als das Format für find -exec.

Dies gibt den Dateinamen und den Inhalt der übereinstimmenden Zeile aus, z

/home/rob/file:text-to-find-here

Optionale Flags, die Sie möglicherweise hinzufügen möchten grep:

  • -i - Suche ohne Berücksichtigung der Groß- und Kleinschreibung
  • -l - Geben Sie nur den Dateinamen aus, in dem die Übereinstimmung gefunden wurde
  • -h - nur die übereinstimmende Zeile ausgeben (nicht den Dateinamen)
RobEarl
quelle
3
Dies entspricht grep 'text-to-find-here'ohne Dateinamen, wenn findnichts gefunden wird. Dies wird hängen bleiben und auf Benutzereingaben warten! Fügen Sie --no-run-if-emptyals eine Option xargs.
Hagello
3
Diese Kombination aus find und xargs funktioniert nicht wie beabsichtigt, wenn Datei- oder Verzeichnisnamen Leerzeichen enthalten (Zeichen, die xargs als Trennzeichen interpretiert). Verwenden Sie find … -exec grep … +. Wenn Sie darauf bestehen, find zusammen mit xargs zu verwenden, verwenden Sie -print0und -0.
Hagello
43
grep -insr "pattern" *
  • i: Ignorieren Sie die Unterscheidung zwischen Groß- und Kleinschreibung sowohl im MUSTER als auch in den Eingabedateien.
  • n: Stellen Sie jeder Ausgabezeile die 1-basierte Zeilennummer in der Eingabedatei voran.
  • s: Unterdrücken Sie Fehlermeldungen zu nicht vorhandenen oder nicht lesbaren Dateien.
  • r: Lesen Sie alle Dateien unter jedem Verzeichnis rekursiv.
enfinet
quelle
3
Können Sie erklären, wie sich Ihre Antwort gegenüber den anderen Antworten verbessert oder wie sie sich ausreichend von diesen unterscheidet?
Amos M. Carpenter
Nicht sehr komplex zu merken, deckt alle Muster ab (Groß- / Kleinschreibung -> aus, enthält Dateinamen und Zeilennummer und führt rekursiv usw. durch). Wenn Sie am Ende "*" verwenden, werden alle Verzeichnisse durchsucht (es müssen keine angegeben werden Pfad- oder Verzeichnisname).
Enfinet
Entschuldigung, ich hätte klarer sein sollen: Es wäre großartig, wenn Sie diese Erklärung in Ihre Antwort aufnehmen könnten. So wie es aussieht, ist es gerade bei so vielen ähnlichen Antworten schwer, aus einer so kurzen Antwort zu erkennen, welchen Vorteil es hätte, sie gegenüber der akzeptierten Antwort oder einer der positiv bewerteten Antworten zu versuchen.
Amos M. Carpenter
6
@ AmosM.Carpenter Eine Sache, die ich an dieser Antwort liebe, ist das Hervorheben des Unterdrückungsarguments, das dabei helfen kann, Rauschen herauszufiltern, das für die Erzielung der gewünschten Ergebnisse keine Rolle spielt. Grep druckt Fehler wie "Funktion nicht implementiert", "Ungültiges Argument", "Ressource nicht verfügbar" usw. usw. für bestimmte "Dateien".
LeetNightshade
@leetNightshade: Ich gehe davon aus, dass Sie Ihren Kommentar an mich richten, weil ich um eine Erklärung für den spärlichen Originalbeitrag gebeten habe. Bitte lesen Sie Fabios großartige Überarbeitung, damit meine vorherigen Kommentare Sinn machen.
Amos M. Carpenter
39

Es gibt ein neues Dienstprogramm namens The Silversearcher

sudo apt install silversearcher-ag

Es arbeitet eng mit Git und anderen VCS zusammen. Sie erhalten also nichts in einem .git oder einem anderen Verzeichnis.

Sie können einfach verwenden

ag "Search query"

Und es wird die Aufgabe für Sie erledigen!

Neil Agarwal
quelle
35

Wie finde ich alle Dateien, die bestimmten Text enthalten, unter Linux? (...)

Ich bin zweimal auf diese Lösung gestoßen:

find / -type f -exec grep -H 'text-to-find-here' {} \;


Wenn Sie find wie in Ihrem Beispiel verwenden, fügen Sie besser -s( --no-messages) zu grepund 2>/dev/nullam Ende des Befehls hinzu, um zu vermeiden, dass viele Nachrichten mit und ohne Berechtigung von :grepfind

find / -type f -exec grep -sH 'text-to-find-here' {} \; 2>/dev/null

find ist das Standardwerkzeug für die Suche nach Dateien - kombiniert mit grep bei der Suche nach bestimmten Texten - auf Unix-ähnlichen Plattformen. DerBefehl find wirdübrigensoft mit xargs kombiniert.

Für denselben Zweck gibt es schnellere und einfachere Tools - siehe unten. Probieren Sie sie besser aus, vorausgesetzt, sie sind auf Ihrer Plattform verfügbar :

Schnellere und einfachere Alternativen

RipGrep - schnellstes Suchwerkzeug:

rg 'text-to-find-here' / -l

Der Silbersucher :

ag 'text-to-find-here' / -l

ack :

ack 'text-to-find-here' / -l

Hinweis: Sie können 2>/dev/nulldiesen Befehlen auch hinzufügen , um viele Fehlermeldungen auszublenden.


Warnung : Wenn Sie dies nicht wirklich vermeiden können, suchen Sie nicht in '/' (dem Stammverzeichnis) , um eine lange und ineffiziente Suche zu vermeiden! In den obigen Beispielen sollten Sie ' / ' durch einen Unterverzeichnisnamen ersetzen , z. B. "/ home", je nachdem, wo Sie tatsächlich suchen möchten ...

Bludzee
quelle
"find ist das Standardwerkzeug für die Suche nach Dateien, die bestimmten Text auf Unix-ähnlichen Plattformen enthalten" scheint mir eher zweideutig. Außerdem rekursiv grep finddurchsucht das Innere von Dateien nicht direkt nach Text. Und vielleicht sind diese zusätzlichen Tools für einige nützlich, aber Oldtimer und diejenigen, die es gewohnt sind, z. B. grepwürden ihnen überhaupt keine Zeit geben ( naja, das werde ich bestimmt nicht). Das heißt aber nicht, dass sie nutzlos sind.
Pryftan
".... mit spezifischem Text ...": Dieser Teil des Satzes war nicht korrekt (weil er sich nicht mit diesem Teil der Suche befasst). Bearbeitet. Vielen Dank.
Bludzee
Freut mich zu helfen! Das einzige , was sonst zu einem sehr sehr schnellen Blick ist das Wort zu ändern Ordner zu Verzeichnis , aber ich weiß , das ist ein Kreuzzug von mir Ich werde nie ganz gewinnen. Nicht aufgeben ...
Pryftan
Warum nicht "Verzeichnis" statt "Ordner", aber warum? Bitte teilen Sie Ihren "Kreuzzug"!
Bludzee
Ich sage stattdessen Verzeichnis verwenden! In Bezug auf: Sie sollten '/' besser durch einen Unterordnernamen ersetzen. Und es ist ein kleiner Ärger von mir. Zumal sogar Windows es früher als 'Verzeichnis' bezeichnet hat. Ah ... vielleicht hast du das verstanden. Warum? Nun, weil es so heißt. Das wird auch auf Dateisystemebene genannt. Und sehen Sie es so: Wurde es jemals genannt (für DOS) fol? Nein natürlich nicht; es wurde genannt dir(und ich glaube es ist immer noch). Ordner ist eine Sache, die für (ich denke) Benutzerfreundlichkeit erfunden wurde, obwohl es in diesem Fall vielleicht für weniger "fortgeschrittene" Benutzer dumm ist?
Pryftan
29

Versuchen:

find . -name "*.txt" | xargs grep -i "text_pattern"
venkat
quelle
5
Dies ist eigentlich ein Paradebeispiel dafür, wann man es NICHT so benutzt xargs. echo "file bar.txt has bar" > bar.txt; echo "file foo bar.txt has foo bar" > "foo bar.txt"; echo "You should never see this foo" > foo; find . -name "*.txt" | xargs grep -i foo # ./foo:You should never see this foo. Das xargshier stimmte mit der FALSCHEN Datei überein und stimmte NICHT mit der beabsichtigten Datei überein. Verwenden Sie entweder eine, find .. -print0 | xargs -0 ...aber das ist eine nutzlose Verwendung einer Pfeife oder besserfind ... -exec grep ... {} +
Shalomb
29

Verwenden pwdSie diese Option, um aus einem beliebigen Verzeichnis, in dem Sie sich befinden, nach unten zu suchen

grep -rnw `pwd` -e "pattern"

Update Abhängig von der verwendeten Grep-Version können Sie diese weglassen pwd. Bei neueren Versionen .scheint dies der Standardfall für grep zu sein, wenn kein Verzeichnis angegeben wird:

grep -rnw -e "pattern"

oder

grep -rnw "pattern"

wird das gleiche tun wie oben!

Mahatmanich
quelle
3
Die Verwendung pwdist überhaupt nicht erforderlich, da dies die Standardeinstellung ist. grep -rnw "pattern"genügt.
fedorqui 'SO hör auf,'
und in der Tat ist das grep -rnwund das, was vor drei Jahren beantwortet wurde, ich sehe nicht, wie diese Antwort Mehrwert schafft.
fedorqui 'SO hör auf,'
Die ausgewählte Antwort zeigt nicht das Standardmuster, und 5
Leute
Was meinst du mit "Standardmuster"? Die akzeptierte Antwort enthält grep -rnw '/path/to/somewhere/' -e "pattern", was Sie hier haben. 5 Stimmen nach 2,3 Millionen Besuchen bedeuten nicht so viel.
Fedorqui 'SO hör auf zu schaden'
Ich stimme zu :-) Was mir in der ursprünglichen Antwort gefehlt hat, ist der Anwendungsfall, dass Sie überhaupt keinen Pfad angeben oder das aktuelle Verzeichnis rekursiv durchsuchen müssen, was sich nicht in der akzeptierten Antwort widerspiegelt. Daher war es eine gute Lernerfahrung über grep, etwas tiefer zu graben.
Mahatmanich
19

grep kann verwendet werden, auch wenn wir nicht nach einer Zeichenfolge suchen.

Einfach laufen,

grep -RIl "" .

druckt den Pfad zu allen Textdateien aus, dh zu solchen, die nur druckbare Zeichen enthalten.

Alex Jasmin
quelle
2
Ich sehe nicht , wie das ist besser als eine bloße Verwendung lsoder find(für die rekursive)
fedorqui ‚schaden SO stop‘
17

Hier finden Sie eine Liste von Befehlen, mit denen Dateien durchsucht werden können.

grep "text string to search” directory-path

grep [option] "text string to search” directory-path

grep -r "text string to search” directory-path

grep -r -H "text string to search” directory-path

egrep -R "word-1|word-2” directory-path

egrep -w -R "word-1|word-2” directory-path
Atul Arvind
quelle
5
Was trägt dies zu den vorhandenen Antworten bei?
fedorqui 'SO hör auf,'
@fedorqui egrepist gleichbedeutend mit grep -Eund es bedeutet, dass --extended-regexpSie Details hier finden können unix.stackexchange.com/a/17951/196072
omerhakanbilici
17

Silver Searcher ist ein großartiges Tool, aber Ripgrep kann noch besser sein.

Es funktioniert unter Linux, Mac und Windows und wurde vor einigen Monaten in den Hacker News geschrieben (dies hat einen Link zu Andrew Gallants Blog, der einen GitHub-Link hat):

Ripgrep - Ein neues Befehlszeilensuchwerkzeug

AAAfarmclub
quelle
15
find /path -type f -exec grep -l "string" {} \;

Erklärung aus Kommentaren

find ist ein Befehl, mit dem Sie Dateien und andere Objekte wie Verzeichnisse und Links in Unterverzeichnissen eines bestimmten Pfads finden können. Wenn Sie keine Maske angeben, die Dateinamen erfüllen sollen, werden alle Verzeichnisobjekte aufgelistet.

-type f specifies that it should proceed only files, not directories etc.
-exec grep specifies that for every found file, it should run grep command, passing its filename as an argument to it, by replacing {} with the filename
Vinod Joshi
quelle
15

Versuchen:

find / -type f -exec grep -H 'text-to-find-here' {} \;

Das wird alle Dateisysteme durchsuchen, da /es sich um den Stammordner handelt.

Für den Home-Ordner verwenden Sie:

find ~/ -type f -exec grep -H 'text-to-find-here' {} \;

Für den aktuellen Ordner verwenden Sie:

find ./ -type f -exec grep -H 'text-to-find-here' {} \;
user4863663
quelle
Vielleicht sind die Details zu Unterschieden in Ordnern für viele offensichtlich ... aber auch für Neulinge sehr hilfreich. +1
Nilon
1
Was trägt dies zu den vorhandenen Antworten bei?
fedorqui 'SO hör auf,'
Nennen wir es meinen Kreuzzug, aber das Wort ist "Verzeichnis". Dies ist nicht Windows (das ohnehin 'Verzeichnis' verwendet hat - vor 9x). Bitte hören Sie auf, "Ordner" zu sagen. Für Ihren letzten Befehl benötigen Sie nicht einmal das '/', nur zu Ihrer Information.
Pryftan
15

Hoffe das ist hilfreich ...

Wenn Sie das grepBit etwas erweitern, um weitere Informationen in der Ausgabe zu erhalten, um beispielsweise die Zeilennummer in der Datei zu erhalten, in der sich der Text befindet, können Sie wie folgt vorgehen:

find . -type f -name "*.*" -print0 | xargs --null grep --with-filename --line-number --no-messages --color --ignore-case "searthtext"

Wenn Sie eine Vorstellung vom Dateityp haben, können Sie Ihre Suche eingrenzen, indem Sie Dateityperweiterungen angeben, nach denen gesucht werden soll, in diesem Fall .pasODER .dfmDateien:

find . -type f \( -name "*.pas" -o -name "*.dfm" \) -print0 | xargs --null grep --with-filename --line-number --no-messages --color --ignore-case "searchtext"

Kurze Erläuterung der Optionen:

  1. . in dem find gibt aus dem aktuellen Verzeichnis an.
  2. -name" *.*": für alle Dateien (-name " *.pas" -o -name " *.dfm"): Nur die *.pasODER- *.dfmDateien, ODER angegeben mit-o
  3. -type f Gibt an, dass Sie nach Dateien suchen
  4. -print0und --nullauf der anderen Seite der |(Pipe) sind die entscheidenden, die den Dateinamen von dem findzum grepeingebetteten in übergeben xargs, wodurch Dateinamen MIT Leerzeichen in den Dateinamen übergeben werden können, sodass grep den Pfad und den Dateinamen als eine Zeichenfolge behandeln kann. und nicht in jedem Raum aufbrechen.
Gert van Biljon
quelle
-name '*.*'ist nicht was du sagst; Eine Datei mit dem Namen "Datei" wird nicht erfasst, da das Muster nicht dem entspricht (keine .ext). *würde aber (naja. Dateien beiseite). Aber es gibt noch eine andere Sache: Wenn Sie alle Dateien möchten, warum sollten Sie sich überhaupt die Mühe machen, einen Dateinamen anzugeben? Kein anderer Kommentar - außer dass es schön ist zu wissen, dass es immer noch Leute gibt, die den MS-Terminologie-Ordner nicht verwenden (was ich, nachdem ich es genug gesagt habe, nicht hinzufügen würde, aber ich wollte auf die etwas falsche Aussage hinweisen, die Sie gemacht haben mit Dateinamen - sowie die Redundanz / Nutzlosigkeit bei 'all').
Pryftan
15

Ein Simple findkann praktisch funktionieren. Alias ​​es in Ihrer ~/.bashrcDatei:

alias ffind find / -type f | xargs grep

Starten Sie ein neues Terminal und geben Sie Folgendes ein:

ffind 'text-to-find-here'
baumelnder Zeiger
quelle
14

Ich habe ein Python-Skript geschrieben, das etwas Ähnliches tut. So sollte man dieses Skript verwenden.

./sniff.py path pattern_to_search [file_pattern]

Das erste Argument pathist das Verzeichnis, in dem wir rekursiv suchen werden. Das zweite Argument pattern_to_searchist ein regulärer Ausdruck, den wir in einer Datei suchen möchten. Wir verwenden das in der Python- re Bibliothek definierte Format für reguläre Ausdrücke . In diesem Skript entspricht das .auch der Zeilenumbruch.

Das dritte Argument file_patternist optional. Dies ist ein weiterer regulärer Ausdruck, der mit einem Dateinamen arbeitet. Es werden nur die Dateien berücksichtigt, die diesem regulären Ausdruck entsprechen.

Zum Beispiel, wenn ich Python-Dateien mit der Erweiterung durchsuchen möchte py enthalten Pool(Wort gefolgt Adaptor, habe ich die folgenden,

./sniff.py . "Pool(.*?Adaptor"  .*py
./Demos/snippets/cubeMeshSigNeur.py:146 
./Demos/snippets/testSigNeur.py:259 
./python/moose/multiscale/core/mumbl.py:206 
./Demos/snippets/multiComptSigNeur.py:268 

Und voila, es generiert den Pfad der übereinstimmenden Dateien und die Zeilennummer, unter der die Übereinstimmung gefunden wurde. Wenn mehr als eine Übereinstimmung gefunden wurde, wird jede Zeilennummer an den Dateinamen angehängt.

Dilawar
quelle
14

Wenn Sie ausschließlich verwenden möchten, findverwenden Sie find + grep:

find /path/to/somewhere/ -type f -exec grep -nw 'textPattern' {} \;

Schritte:

1. Verwenden Sie findzum Durchsuchen von Dateien.
2. Führen Sie dann ausgrep alle aus.

Dies kann Ihnen die Möglichkeit geben find, Dateien zu finden.

  • Verwenden -name PatternSie diese Option, wenn Sie grepnur bestimmte Dateien verwenden möchten :

    find /path/to/somewhere/ -type f -name \*.cpp -exec grep -nw 'textPattern' {} \;

Sie können damit spielen und verschiedene Optionen verwenden find, um Ihre Dateisuche zu verbessern oder einzugrenzen.

BreakBadSP
quelle
Was ist der Unterschied? Funktioniert es mit Leerzeichen im Dateipfad?
Peter Mortensen
13

Verwenden:

grep -c Your_Pattern *

Dadurch wird gemeldet, wie viele Kopien Ihres Musters in jeder der Dateien im aktuellen Verzeichnis vorhanden sind.

Dr_Hope
quelle
13

grep ist dein guter Freund, um dies zu erreichen.

grep -r <text_fo_find> <directory>

Wenn Sie sich nicht für den Fall des zu findenden Textes interessieren, verwenden Sie:

grep -ir <text_to_find> <directory>
Prash
quelle
In meinem Fall sieht es so aus, als würde es überall suchen, auch wenn ich das Verzeichnis spezifiziere
Pathros
@Pathros Wahrscheinlich mit aktivierter Rekursion und dem von Ihnen angegebenen Verzeichnis zu tun. Anders ausgedrückt: Rekursion verändert die Dinge auf diese Weise.
Pryftan
@Pathros Oh, und wenn die Suchzeichenfolge -s enthält, möchten Sie sie --zuerst an grep übergeben. das kann sonst interessante Nebenwirkungen verursachen!
Pryftan
13

Ich bin fasziniert, wie einfach grep es mit 'rl' macht:

grep -rl 'pattern_to_find' /path/where/to/find

-r to recursively find a file / directory inside directories..
-l to list files matching the 'pattern'

Verwenden Sie '-r' ohne 'l', um die Dateinamen gefolgt von Text anzuzeigen, in dem sich das Muster befindet !

grep -r 'pattern_to_find' /path/where/to/find

Es funktioniert einfach perfekt ...

nitinr708
quelle
Dies funktioniert auch in Git Bash (Windows).
Peter Mortensen
Dies bedeutet jedoch, dass jede Datei durchsucht werden muss (z. B. kein Filter für den Dateinamen oder die Dateierweiterungsebene .txt). Oder gibt es eine Möglichkeit, das zu tun?
Peter Mortensen
12

So suchen Sie nach der Zeichenfolge und geben nur diese Zeile mit der Suchzeichenfolge aus:

for i in $(find /path/of/target/directory -type f); do grep -i "the string to look for" "$i"; done

z.B:

for i in $(find /usr/share/applications -type f); \
do grep -i "web browser" "$i"; done

So zeigen Sie den Dateinamen an, der die Suchzeichenfolge enthält:

for i in $(find /path/of/target/directory -type f); do if grep -i "the string to look for" "$i" > /dev/null; then echo "$i"; fi; done;

z.B:

for i in $(find /usr/share/applications -type f); \
do if grep -i "web browser" "$i" > /dev/null; then echo "$i"; \
fi; done;

quelle
1
Ich sehe nur Nachteile im Vergleich zur Verwendung find … -exec grep 'str' {} \;(wenn Sie überhaupt verwenden müssen find).
Phk
1
Dies würde schrecklich brechen, wenn eine der Dateien in findenthaltenen Leerzeichen gefunden würde. Sie könnten greppingdie falschen Dateien erhalten und / oder die richtigen Dateien insgesamt vermissen. Verwenden find ... -exec grep ...Sie es einfach, wenn Sie es benötigen find. In diesem Fall grep -r ...reicht jedoch ein.
Shalomb
1
Was bringt es, eine Schleife über die Ergebnisse von find zu verwenden, um dann grep? Dies wird unnötig kompliziert.
fedorqui 'SO hör auf,'
12

Es gibt ein ackTool, das genau das tut, wonach Sie suchen.

http://linux.die.net/man/1/ack

ack -i search_string folder_path/*

Sie können die -iSuche bei Groß- und Kleinschreibung ignorieren

Kumpel
quelle
2
Was trägt dies zu den vorhandenen Antworten bei? Dies wurde bereits vor mehr als drei Jahren vorgeschlagen.
fedorqui 'SO hör auf,'
1
@ Fedorqui 1) keine Rohrleitungen! 2) Verwenden Sie reguläre Ausdrücke. 3) Abrufen von Zeilennummern, Dateinamen mit relativem Pfad, hervorgehobenem Text usw., die für die Bearbeitung nach der Suche nützlich sind, z. B. "vim + lineno path / file.cpp", bringt Sie direkt an die Zeile, die Sie nicht interessiert. Siehe die Ausgabe des Befehls "ack include \ | hpp", der die Schlüsselwörter "include" oder "hpp" unter meinem Suchordner und meinen Unterordnern sucht. Ich hoffe, der Punkt ist klar. Hier ist die Beispielausgabe (Schlüsselwort-Highlights können mit einfachem Text nicht angezeigt werden) process / child.hpp 11: boost / process / child.hpp process / all.hpp 21: #include <boost / process / execute.hpp>
Pal
12

Alle vorherigen Antworten schlagen grep and find vor. Aber es gibt noch einen anderen Weg: Verwenden Midnight Commander

Es ist ein kostenloses Dienstprogramm (30 Jahre alt, durch die Zeit bewiesen), das visuell ist, ohne GUI zu sein. Es hat unzählige Funktionen, und das Finden von Dateien ist nur eine davon.

Peter M. - steht für Monica
quelle
Ranger wäre in der gleichen Idee
Nilon
11

Der folgende Befehl funktioniert für diesen Ansatz einwandfrei:

find ./ -name "file_pattern_name"  -exec grep -r "pattern" {} \;
Pradeep Goswami
quelle
2
Was ist der Sinn der Verwendung findund dann grep -r? Sie sind für dasselbe gedacht, daher ist dies überflüssig.
Fedorqui 'SO hör auf zu schaden'
ohh !! korrigiert, Eigentlich finden ist für das Ausführen von grep auf gefilterten Dateien und nicht alle, danke
Pradeep Goswami
2
Trotzdem macht dies keinen Sinn, mit dem Sie filtern können find.
fedorqui 'SO hör auf,'
11

Vermeiden Sie den Ärger und installieren Sie ack-grep. Es beseitigt viele Probleme mit Berechtigungen und Angeboten.

apt-get install ack-grep

Gehen Sie dann zu dem Verzeichnis, das Sie suchen möchten, und führen Sie den folgenden Befehl aus

cd /
ack-grep "find my keyword"
Kareem
quelle