Frage Wie verwende ich den "grep" -Befehl, um Text einschließlich Unterverzeichnissen zu finden?


Ich möchte alle Dateien finden, die eine bestimmte Textfolge enthalten. Das grep Befehl funktioniert, aber ich weiß nicht, wie man es für jedes Verzeichnis verwendet (ich kann es nur für mein aktuelles Verzeichnis tun). Ich habe versucht zu lesen man grep, aber es gab keine Hilfe.


292
2017-08-01 11:38


Ursprung


grep -RIn <yor pattern> * Sucht in allen Textdateien nach aktuellen Verzeichnissen. Ich bin mir nicht sicher, wie ich meine Suche rekursiv in Dateimustern wie * .C mit nur grep durchführen kann
Wildcard mit --include="*.C" Option, @ user311346, dank @Lekensteyn. - Bob Stein
Verwenden Sie die Kombination "find" und "grep", um rekursiv nach Dateien im aktuellen Verzeichnis und allen Unterverzeichnissen zu suchen. Überprüfen Sie dies wilddiary.com/find-files-containing-my-text - Drona


Antworten:


Es wäre besser zu benutzen

grep -rl "string" /path

woher

  • -r (oder --recursive) Option wird verwendet, um auch alle Unterverzeichnisse von zu durchlaufen /path, wohingegen
  • -l (oder --files-with-matches) Option wird verwendet, um nur die Dateinamen übereinstimmender Dateien zu drucken, und nicht die übereinstimmenden Zeilen (dies könnte auch die Geschwindigkeit verbessern, vorausgesetzt, dass grep stoppe das Lesen einer Datei bei der ersten Übereinstimmung mit dieser Option).

375
2017-08-01 11:55



Wenn "string" ein zu suchendes Textmuster ist, ist es besser, diese Funktionalität zu verwenden, da sonst Probleme auftreten können, wenn die Zeichenfolge Punkte oder Sonderzeichen enthält, die in regulären Ausdrücken Bedeutung haben und nicht nur ein Punkt, der als Zeichenfolge gefunden werden soll , wie es ist. Dann würde ich verwenden -rlF Schalter, -F für "feste Zeichenfolge" (und nicht regexp - zum Beispiel). Natürlich, wenn die Aufgabe Regexps verwendet, entschuldige mich. Sicher, die gleiche Theorie ohne -r auch, ich sehe oft, dass Leute grep sucht "Text" und es kann Probleme, die spezielle, die etwas wie eine Regexp bedeuten. - LGB
Es gibt auch die -i Flag, das den Fall ignoriert. - Marco Ceppi♦
Ich würde nur das zeigen --recursive Option gibt es eine Menge Optionen und Nutzungsszenarien, über die man sprechen kann. Ich begann von der @dmityugov akzeptierte Antwort und modifiziert, um ohne zu arbeiten find. - enzotib
@N.N .: fertig :-) - enzotib
@ScottBiggs: mit der Option --include '*.h' - enzotib


Wenn Sie nach Zeilen suchen, die in Dateien übereinstimmen, lautet mein bevorzugter Befehl:

grep -Hrn 'search term' path/to/files
  • -H bewirkt, dass der Dateiname gedruckt wird (impliziert, wenn mehrere Dateien durchsucht werden)
  • -r macht eine rekursive Suche
  • -n bewirkt, dass die Zeilennummer gedruckt wird

path/to/files kann sein . im aktuellen Verzeichnis suchen

Weitere Optionen, die ich sehr nützlich finde:

  • -I Binärdateien ignorieren (Ergänzung: -a behandle alle Dateien als Text)
  • -F behandeln search term als ein Literal, kein regulärer Ausdruck
  • -i Suche nach Groß- und Kleinschreibung
  • --color=always um Farben auch beim Durchstecken zu erzwingen less. Zu machen less Unterstützungsfarben müssen Sie die verwenden -r Möglichkeit:

    grep -Hrn search . | less -r
    
  • --exclude-dir=dir nützlich zum Ausschließen von Verzeichnissen wie .svn und .git.

Example output


136
2017-08-01 12:27



-H auf einen Ordner ist redundant, wenn es mehr als eine Datei gibt, wie es wahrscheinlich ist. In der Tat sagt die Manpage -H, --with-filename: Print the file name for each match. This is the default when there is more than one file to search. - enzotib
Ich wusste das nicht, es funktionierte immer so, wie ich es erwartet hatte. Es ist mein Standardbefehl bei der Suche nach Dateien. - Lekensteyn
Gibt es eine Möglichkeit, nur Dateien mit einer, sagen wir, .a Erweiterung zu betrachten (und diese mit -r zu kombinieren)? - user2413
@ user2413 Versuchen Sie es --include '*.*' - Lekensteyn
@enzotib Nur eine FYI: Ich bekomme nicht die nette saubere Ausgabe von jeder Zeile in jeder Datei, wo mein Text mit -rln oder -rl erscheint, aber ich mache mit -Hrn. Redundant oder nicht, es sieht aus wie der Screenshot oben mit den Optionen -Hrn. Es scheint auch nicht wie -n funktioniert ohne -H. - SgtPooki


Ich glaube, du kannst so etwas verwenden:

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

Erklärung von Kommentaren

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

  • -type f gibt an, dass nur Dateien verarbeitet werden sollen, keine Verzeichnisse usw.
  • -exec grep Gibt an, dass für jede gefundene Datei der Befehl grep ausgeführt und der Dateiname als Argument übergeben werden soll, indem er ersetzt wird {} mit dem Dateinamen

21
2017-08-01 11:48



Nur für diejenigen, die es nicht wissen, hinzufügen -name '*.py' beschränkt die Übereinstimmungen auf Dateien mit der Endung '.py'. - Daniel F
Ich mag, dass dies Clients abdeckt, die in ihrem grep-Befehl nicht -R implementiert haben. - Aviose


Mein Standardbefehl ist

grep -Rin string *

Ich benutze ein Capitol 'R' weil ls verwendet es für rekursiv. Da grep beides akzeptiert, gibt es keinen Grund, es nicht zu benutzen.

EDIT: per HVNSweeting, anscheinend -R folgt Symlinks wo als -r wird nicht.


17
2017-08-01 14:43



Um auch in versteckten Dateien zu suchen, führen Sie shopt -s dotglob (merken -s als "gesetzt"). Seien Sie vorsichtig beim Entfernen von Dateien. Wenn du dotglob aktiviert hast, rm -r * entfernt alles im aktuellen Verzeichnis, aber ebenfalls das Verzeichnis darüber, weil .. Streichhölzer. Um dotglob zu deaktivieren, verwenden Sie shopt -u dotglob ("nicht festgelegt") Die Änderungen sind jedoch nur vorübergehend, sie gelten nur für die aktuelle Shell. - Lekensteyn
Ich habe das vergessen. Gibt es eine Möglichkeit, es für die eine Linie zu setzen? etwas wie shopt -s dotglob & <grep cmd> & shopt -y dotglob nur bequemer? Auf diese Weise müssen wir uns keine Sorgen machen, dass wir es zurücksetzen können - user606723
Außerdem ist es wahrscheinlich einfacher zu benutzen grep -Rin string . in den meisten dieser Fälle. Ich benutze nur *, weil es natürlicher erscheint. - user606723
Wenn Sie rekursive Grep machen, dann können Sie einfach von "." Anstatt von "*". Kein Dotglob benötigt. - Michał Šrajer
Stimme dies ab, eine Sache erwähnt nicht in Manpage ist R folgt symbolischen Links, r nicht - HVNSweeting


Wenn du etwas Neues ausprobieren willst, gib es ack ein Schuss. Der Befehl zum rekursiven Durchsuchen des aktuellen Verzeichnisses nach string ist:

ack string

Die Installation ist ziemlich einfach:

curl http://betterthangrep.com/ack-standalone > ~/bin/ack && chmod 0755 !#:3

(Vorausgesetzt, Sie haben bereits das Verzeichnis ~/bin und es ist vorzugsweise in deinem PATH.)


11
2017-08-01 15:09



Oder einfach apt-get installieren Sie ack-grep (und fügen Sie alias ack = ack-grep zu Ihrem .bashrc hinzu) - markijbema
Was bedeuten die letzten Parameter? chmod Befehl tun? Sind sie spezifisch für? chmod oder sind sie bash verwandt? !#:3 Teil)? - Elliott Darfink
@ ElliottDarfink Das verwendet Bash Historienfunktion - ! ist ein Ereignisbezeichner. Sie sind ziemlich mächtig, um Wiederholungen zu vermeiden. !#:3 verweist auf das dritte Token der Befehlszeile, d. h. ~/bin/ack in diesem Fall. - Konrad Rudolph


Der Befehl rgrep ist für solche Bedürfnisse gedacht

Wenn nicht verfügbar, können Sie es so erhalten

mkdir -p ~/bin
cd ~/bin
wget http://sdjf.esmartdesign.com/files/rgrep
chmod +x rgrep

Sie können direkt in Ihre Standard-Grep-Optionen wie oben beschrieben setzen.

Ich benutze persönlich

[[  ${#args} -lt 5 && "${args//[[:space:]]/}" == "-i" ]] && args="-Hin"
args="${args:--Hns} --color=auto"

verwandtes Thema: wie man rgrep immer mit Farbe benutzt


3
2018-01-02 13:58



rgrep wird vom grep-Paket bereitgestellt, das standardmäßig in Ubuntu installiert wird. - karel


Update 2:

Diese Befehlszeile verwendet find und grep behebt das Problem:

$ find path_to_search_in -type f -exec grep -in searchString {} 2> /dev/null +

--color=<always or auto> für farbige Ausgabe:

$ find path_to_search_in -type f \
            -exec grep --color=always -in searchString {} 2>/dev/null +

Beispiel:

$ find /tmp/test/ -type f -exec grep --color=auto -in "Search string" {} 2>/dev/null +

Ein Beispiel, das im folgenden Snapshot ausgeführt wird: snap1


Update 1:

Sie können folgenden Code versuchen; als eine Funktion in Ihrem .bashrcoder .bash_aliases oder in einem Skript:

wherein () 
{ 
    for i in $(find "$1" -type f 2> /dev/null);
    do
        if grep --color=auto -i "$2" "$i" 2> /dev/null; then
            echo -e "\033[0;32mFound in: $i \033[0m\n";
        fi;
    done
}

Verwendung: wherein /path/to/search/in/ searchkeyword

Beispiel:

$ wherein ~/Documents/ "hello world"

(Hinweis: Wie in den Kommentaren von @enzotib empfohlen, funktioniert dies nicht mit Dateien / Verzeichnissen einschließlich Leerzeichen in ihren Namen.)


Original Beitrag

Um nach der Zeichenfolge zu suchen und nur diese Zeile mit der Suchzeichenfolge auszugeben:

$ 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 mit dem Suchstring an:

$ 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;

2
2018-01-25 11:11



Fehler bei Dateinamen mit Leerzeichen. Der Fehler wird durch die Tatsache verdeckt, dass stderr nicht angezeigt wird. - enzotib
@enzotib Danke, dass du darauf hingewiesen hast .. das ist immernoch ungelöst für die angegebene Funktion .. Ich habe einen weiteren Einzeiler hinzugefügt. - precise
Jetzt ist die Antwort ähnlich der von @dmityugov. - enzotib
Ja, aber in diesem Sinne sind die meisten Antworten auf dieser Seite ähnlich, wenn sie überprüfen grep, daneben ist die Untermenge, die verwendet find mit grep... aber wenn Sie verschiedene Schalter und Tweaks als eindeutige Antwort akzeptieren, wird wahrscheinlich auch meine hier passen .. oder unterscheiden Sie sich? Das letzte Update macht das, was ich in meiner Suche haben möchte: Dateinamen mit Zeilen mit Suchschlüssel und Zeilennr. zu :) und farbigen Ausgang und Fehlerfilter für bessere Lesbarkeit. - precise


Ich mache das mit Xargs, einem sehr unterschätzten Befehl

find ./ -type f -print0 | xargs -0 grep 'string_you_are_looking_for'

find ./ gibt Ihnen eine rekursive Liste aller Dateien in einem aktuellen Ordner dann leiten Sie es an xargs weiter, das den Befehl grep für jede dieser Dateien ausführt


1
2017-08-01 15:30



Verwenden xargs ohne -print0 Option zu find und -0 Option zu xargs ist veraltet, wird bei Dateinamen, die Leerzeichen enthalten, fehlschlagen. - enzotib
@enzotib ich habe die antwort wie du vorgeschlagen bearbeitet.- bitte nachlesen und wenn es nötig ist zu bearbeiten und zu korrigieren, werde ich gerne von dir redigieren. Danke - αғsнιη
@KasiyA: Es ist jetzt ok, entfernte mein Downvote. - enzotib


Ich weiß, dass es hier viele Antworten gibt, aber hier ist eine Alternative, wenn Sie beim Durchsuchen der Dateien weitere Einschränkungen hinzufügen möchten:

find . -type f -exec grep --quiet string_to_look_for {} ';' -print

Das funktioniert weil grep gibt 0 zurück, wenn es ein Ergebnis gefunden hat, 1 andernfalls. Zum Beispiel können Sie Dateien finden, die 1 MB groß sind und etwas enthalten:

find . -type f -exec grep --quiet string_to_look_for {} ';' -size 1M -print

Bei mehreren Anforderungen möchten Sie wahrscheinlich das Optimierungsflag verwenden -O das gibt es in GNU Grep.


0
2018-03-11 13:56





Ein Skript (find-in-code) zum Suchen in C, CPP-Code:

#!/bin/sh

find . \( -iname "*.c" -o -iname "*.cpp" -o -iname "*.h" \) -type f -print0 | xargs -0 grep --color -n "$1"

Benutzen:

find-in-code "search string"

0
2018-06-11 16:49





grep (GNUoder BSD)

Sie können verwenden grep Werkzeug zum rekursiven Durchsuchen des aktuellen Ordners mit -r Parameter, wie:

grep -r "pattern" .

Hinweis: -r - Durchsuchen Sie Unterverzeichnisse rekursiv.

Um in bestimmten Dateien zu suchen, können Sie a verwenden Globbing-Syntax sowie:

grep "class foo" **/*.c

Hinweis: Durch Verwendung von Globbing-Option (**), scannt er alle Dateien rekursiv mit einer bestimmten Erweiterung oder einem bestimmten Muster. Um diese Syntax zu aktivieren, führen Sie Folgendes aus: shopt -s globstar. Sie können auch verwenden **/*.* für alle Dateien (außer versteckt und ohne Erweiterung) oder irgendein anderes Muster.

Wenn Sie den Fehler haben, dass Ihr Argument zu lang ist, sollten Sie Ihre Suche einschränken oder verwenden find Syntax stattdessen wie:

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 verwenden ripgrep stattdessen, wie:

rg "pattern" .

Überprüfen Sie die Dokumentation, die Installationsschritte oder den Quellcode auf dem GitHub Projektseite.

Es ist viel schneller als jedes andere Werkzeug wie GNU/BSD  grep, ucg, ag, sift, ack, pt oder ähnlich, da es auf Rosts Regex-Engine die endliche Automaten, SIMD und aggressive wörtliche Optimierungen verwendet, um die Suche sehr schnell zu machen.

Es unterstützt Ignoriermuster, die in angegeben sind .gitignore Dateien, so dass ein einzelner Dateipfad gleichzeitig mit mehreren Glob-Mustern verglichen werden kann.


Sie können die allgemeinen Parameter verwenden wie:

  • -i - Unsensitives Suchen.
  • -I - Ignoriere die Binärdateien.
  • -w - Suchen Sie nach den ganzen Wörtern (im Gegensatz zur Teilwortübereinstimmung).
  • -n - Zeigen Sie die Linie Ihres Spiels.
  • -C/--context (z.B. -C5) - Erhöht den Kontext, so dass Sie den umgebenden Code sehen.
  • --color=auto - Markieren Sie den passenden Text.
  • -H - Zeigt den Dateinamen an, wo der Text gefunden wurde.
  • -c - Zeigt die Anzahl der übereinstimmenden Zeilen an. Kann mit kombiniert werden -H.

0
2018-04-11 11:21