Linux / Befehl grep: Text suchen und Befehlsausgabe filtern
grep ist ein Befehl, der verwendet wird, um Zeilen zu finden, die einem bestimmten Muster in Dateien oder der Befehlsausgabe entsprechen. Er unterstützt nicht nur einfache Suchen, sondern auch das Ignorieren der Groß-/Kleinschreibung, das Auswählen von nicht übereinstimmenden Zeilen, die rekursive Verzeichnissuche, reguläre Ausdrücke und die Anzeige des umgebenden Kontexts.
Die einfachste Form ist grep 'pattern' filename. Da das Muster Zeichen enthalten kann, die in der Shell eine spezielle Bedeutung haben, ist es sicherer, es regelmäßig in einfache Anführungszeichen zu setzen.
Was ist der grep-Befehl?
grep liest Eingaben zeilenweise und gibt Zeilen aus, die dem Muster entsprechen. Der Name stammt von dem Befehlsausdruck im Unix-Texteditor ed, g/re/p, was bedeutet, Zeilen zu finden und auszudrucken, die einem regulären Ausdruck im gesamten Bereich entsprechen.
Wenn Sie keine Datei zum Suchen angeben, liest es von der Standardeingabe, sodass Sie die Ausgabe eines anderen Befehls weiterleiten können, um sie zu durchsuchen. Die Standardsyntax für Muster von GNU grep ist Basic Regular Expression (BRE), und die Verwendung von -E ermöglicht die Verwendung von Extended Regular Expression (ERE).
Grundsyntax und erste Suche
Die Grundsyntax ist wie folgt. Eckige Klammern kennzeichnen optionale Elemente, geben Sie sie also nicht im eigentlichen Befehl ein.
grep [option] 'pattern' [file...]
Um Zeilen zu finden, die ERROR in app.log enthalten, führen Sie Folgendes aus.
grep 'ERROR' app.log
Wenn Sie mehrere Dateien angeben, erscheint der Dateiname zusammen mit jedem Ergebnis.
grep 'ERROR' app.log worker.log
Sie können auch die Standardausgabe durchsuchen. Der folgende Befehl zeigt Zeilen in den Kernel-Meldungen, die usb enthalten, unabhängig von Groß- und Kleinschreibung.
dmesg | grep -i 'usb'
Häufig verwendete grep-Optionen
| Option | Funktion | Beispiele für die Verwendung |
|---|---|---|
-i |
Unabhängig von Groß- und Kleinschreibung suchen | grep -i 'error' app.log |
-v |
Zeilen auswählen, die nicht übereinstimmen | grep -v '^#' config |
-n |
Zeilennummern im Ergebnis anzeigen | grep -n 'TODO' main.c |
-w |
Das Muster als ganzes Wort suchen | grep -w 'cat' words.txt |
-x |
Die gesamte Zeile auswählen, wenn sie dem Muster entspricht | grep -x 'enabled' status.txt |
-F |
Das Muster als festen String behandeln, nicht als regulären Ausdruck | grep -F 'a.b' data.txt |
-E |
Verwenden Sie erweiterte reguläre Ausdrücke | grep -E 'error|failed' app.log |
-r |
Unterverzeichnisse rekursiv durchsuchen | grep -r 'listen' /etc/nginx |
-l |
Nur übereinstimmende Dateinamen ausgeben | grep -rl 'deprecated' src |
-c |
Die Anzahl der übereinstimmenden Zeilen pro Datei ausgeben | grep -c 'ERROR' app.log |
-A, -B, -C |
Den Kontext nach, vor oder um übereinstimmende Zeilen ausgeben | grep -C 2 'panic' app.log |
Die obigen Optionen können kombiniert werden. Zum Beispiel wird grep -in 'error' app.log suchen, während die Groß-/Kleinschreibung ignoriert wird, und auch Zeilennummern anzeigen. Detailliertes Verhalten und GNU-Erweiterungsoptionen finden Sie in der offiziellen GNU Grep-Dokumentation.
Unterscheidung zwischen Zeichenketten und regulären Ausdrücken
Feste Zeichenketten mit -F suchen
Zeichen, die in regulären Ausdrücken eine besondere Bedeutung haben, wie Punkte, Sternchen und Klammern, können mithilfe von -F buchstäblich gesucht werden. Im folgenden Befehl wird der Punkt als tatsächlicher Punkt und nicht als irgendein Zeichen behandelt.
grep -F '192.168.0.1' access.log
Wenn der Suchbegriff ein einfacher Textstring ist, können unnötige Escape-Zeichen reduziert und Ihre Absicht klarer gemacht werden.
Verwenden Sie erweiterte reguläre Ausdrücke mit -E
Die Verwendung von -E ermöglicht es Ihnen, die Syntax erweiterter regulärer Ausdrücke wie |, +, ? und Klammern lesbarer zu verwenden. Das folgende Beispiel findet Zeilen, die eines von ERROR, WARN oder FATAL enthalten.
grep -E 'ERROR|WARN|FATAL' app.log
In GNU grep liegt der Unterschied zwischen grundlegenden und erweiterten regulären Ausdrücken hauptsächlich in der Notation. Wenn die Kompatibilität mit anderen Umgebungen wichtig ist, prüfen Sie die grep-Implementierung und unterstützten Optionen des Zielsystems.
Geben Sie den Anfang und das Ende einer Zeile an
Das Dach (^) steht für den Anfang einer Zeile und das Dollarzeichen ($) für das Ende einer Zeile. Eine leere Zeile kann mit ^$ gefunden werden, bei der keine Zeichen zwischen Anfang und Ende stehen.
grep '^server' config.txt grep 'completed$' job.log grep '^$' notes.txt
Um leere Zeilen und Kommentarzeilen aus einer Konfigurationsdatei auszuschließen, können die beiden Bedingungen nacheinander wie folgt angewendet werden.
grep -v '^[[:space:]]*#' app.conf | grep -v '^[[:space:]]*$'
Die Suchreichweite genau einschränken
Ganze Wörter und ganze Zeilen abgleichen
-w wählt Zeilen aus, bei denen das Muster dem gesamten Wort entspricht. Zum Beispiel findet grep -w 'cat' cat, wählt jedoch cat innerhalb von category nicht aus.
grep -w 'root' /etc/passwd
-x wählt eine Zeile nur aus, wenn die gesamte Zeile genau dem Muster entspricht.
grep -x 'active' service-status.txt
Nicht übereinstimmende Zeilen finden
-v kehrt die Auswahl um. Das folgende Beispiel gibt nur Zeilen aus, die DEBUG nicht enthalten.
grep -v 'DEBUG' app.log
In Kombination mit -i können Sie ohne Berücksichtigung der Groß- und Kleinschreibung ausschließen.
grep -iv 'debug' app.log
Mehrere Muster gleichzeitig durchsuchen
Die mehrfache Verwendung von -e ermöglicht es Ihnen, jedes Muster separat anzugeben. Sie müssen sie nicht zu einem einzigen komplexen regulären Ausdruck kombinieren, wodurch sie in Skripten leichter lesbar sind.
grep -e 'ERROR' -e 'FATAL' app.log
Wenn es viele Muster gibt, können Sie eine Datei mit jeweils einem Muster pro Zeile erstellen und diese mit -f einlesen.
grep -f patterns.txt app.log
Rekursives Durchsuchen ganzer Verzeichnisse
Unterschied zwischen -r und -R
-r durchsucht rekursiv Dateien im angegebenen Verzeichnis. Es folgt symbolischen Links, die direkt in der Befehlszeile angegeben sind, überspringt jedoch symbolische Links, die während der rekursiven Suche gefunden werden.
grep -rn 'database_url' ./config
GNU grep’s -R folgt symbolischen Links, die bei rekursiven Suchen angetroffen werden. Da es zyklischen Verweisen folgen oder einen größeren Bereich als erwartet durchsuchen kann, verwenden Sie es nur, wenn die Absicht klar ist.
Ein- und Ausschließen von Dateitypen
--include sucht nur nach den angegebenen Dateinamensmustern, und --exclude überspringt Dateien, die übereinstimmen. Setzen Sie Muster in Anführungszeichen, damit die Shell Sternchen nicht vorher erweitert.
grep -rn --include='*.conf' 'timeout' /etc grep -rn --exclude='*.min.js' 'deprecated' ./src
Um bestimmte Verzeichnisse auszuschließen, verwenden Sie --exclude-dir.
grep -rn --exclude-dir='.git' --exclude-dir='node_modules' 'api_key' .
Nur übereinstimmende Dateinamen prüfen
Wenn Sie eine Liste von Dateien anstelle von übereinstimmendem Inhalt benötigen, verwenden Sie -l. Jede Datei wird nach dem ersten Treffer nicht weiter durchsucht, was ebenfalls gut für den Zweck passt.
grep -rl --include='*.html' 'jb-heading' .
Umgekehrt, um nur Dateien ohne übereinstimmende Muster zu finden, verwenden Sie das Großbuchstaben -L.
grep -rL --include='*.html' 'jb-heading' .
Ergebnis in einem lesbaren Format ausgeben
Zeilennummern und Dateinamen anzeigen
-n zeigt die Zeilennummern der übereinstimmenden Zeilen an. Selbst beim Durchsuchen einer einzelnen Datei kann man zur Anzeige des Dateinamens GNUs grep’s -H verwenden, und um den Dateinamen zu verbergen, verwendet man -h.
grep -nH 'listen' nginx.conf
Anzeigen des Kontexts vor und nach übereinstimmenden Zeilen
Wenn es schwierig ist, die Ursache nur anhand der Fehlermeldungen zu bestimmen, verwenden Sie -A, -B oder -C, um die umliegenden Zeilen zu sehen. Die Zahl gibt an, wie viele zusätzliche Zeilen ausgegeben werden.
grep -A 3 'ERROR' app.log grep -B 2 'ERROR' app.log grep -C 2 'ERROR' app.log
-A 3 fügt 3 Zeilen danach hinzu, -B 2 fügt 2 Zeilen davor hinzu, und -C 2 fügt 2 Zeilen davor und danach hinzu.
Nur den passenden Teil drucken
-o druckt nur den Teil, der dem Muster entspricht, nicht die gesamte Zeile. Wenn es mehrfach in einer Zeile übereinstimmt, wird jede Übereinstimmung separat gedruckt.
grep -oE '[0-9]{3}-[0-9]{4}' contacts.txt
Mit --color=auto heben Sie Treffer im Terminal hervor. Verwenden Sie bei einer Umleitung in eine Datei oder einen anderen Befehl auto oder never, damit keine Farbsteuerzeichen in die weiterverarbeitete Ausgabe gelangen.
Verwendung in Protokollen und Befehlsausgaben
Fehler in den aktuellen Protokollen finden
Um nur den kürzlichen Bereich statt des gesamten Logs zu durchsuchen, verbinden Sie es mit tail.
tail -n 500 app.log | grep -iE 'error|failed|fatal'
Wenn Sie kontinuierlich neue, der Datei hinzugefügte Logs filtern möchten, können Sie es wie folgt verwenden.
tail -F app.log | grep --line-buffered 'ERROR'
--line-buffered ist eine GNU-Erweiterungsoption, die den Ausgabepuffer bei jedem eingehenden Eintrag leert, wodurch Verzögerungen in der Pipe reduziert werden. Methoden zum Tracing, einschließlich Log-Rotation, finden Sie unter How to Use the Linux tail Command.
Filtern von Service- und Prozessergebnissen
Sie können nach einem bestimmten Servicenamen in der systemctl-Ausgabe suchen.
systemctl list-unit-files | grep 'nginx'
Wenn Ihr Ziel nur darin besteht, die Existenz eines Prozesses zu prüfen, ist pgrep oft direkter als ps | grep. Um mit dem Befehlsnamen und seinen Argumenten zusammen zu suchen, können Sie ihn wie folgt ausführen.
pgrep -af 'nginx'
Zählen der passenden Zeilen
-c gibt die Anzahl der passenden Zeilen aus, nicht die Anzahl der Übereinstimmungen. Auch wenn eine Zeile das Muster mehrfach enthält, wird diese Zeile nur einmal gezählt.
grep -c 'ERROR' app.log
Um alle passenden Vorkommen in einer Zeile zu zählen, können Sie jede Übereinstimmung mit -o trennen und dann mit wc -l zählen.
grep -o 'ERROR' app.log | wc -l
Existenzprüfung ohne Ausgabe
-q druckt keine Ergebnisse und gibt nur einen Exit-Status zurück. Es eignet sich zum Überprüfen der Existenz eines Musters in einer Shell-Bedingung.
if grep -q 'ready' status.log; then echo 'Service ready' fi
Verstehen des grep-Exit-Status
grep übermittelt Suchergebnisse nicht nur über den Ausgabestring, sondern auch über den Exit-Status. Typischerweise gibt es 0 zurück, wenn es Übereinstimmungen in den Zeilen gibt, 1, wenn keine Übereinstimmungen vorhanden sind, und 2, wenn eine Datei nicht gelesen werden kann oder ein Syntaxproblem vorliegt.
| Exit-Status | Bedeutung | Entscheidung in Skripten |
|---|---|---|
0 |
Eine oder mehrere Übereinstimmungen gefunden | Als ob die Bedingung wahr wäre, verarbeiten |
1 |
Keine Übereinstimmung gefunden | Könnte ein normales Suchergebnis sein |
2 |
Fehler aufgetreten | Überprüfen Sie die Eingabedatei, Berechtigungen oder das Muster |
Daher sollten Sie nicht schließen, dass die Befehlsausführung selbst fehlgeschlagen ist, nur weil keine Ergebnisse vorliegen. In der Automatisierung müssen Sie zwischen 1 und einem tatsächlichen Fehler 2 unterscheiden. GNU grep -q kann mit dem Status 0 enden, wenn ein Treffer gefunden wird, selbst wenn es andere Fehler gibt. Wenn also die Erkennung von Fehlern in allen Eingabedateien wichtig ist, ist eine separate Überprüfung erforderlich.
Häufige Probleme und Lösungen
Wenn das Muster mit einem Bindestrich beginnt
-ERROR-Muster wie dieses können mit Optionen verwechselt werden. Setzen Sie das Muster nach --, was das Ende der Optionen anzeigt.
grep -- '-ERROR' app.log
Wenn die Meldung 'Binärdatei stimmt überein' erscheint
Wenn GNU grep feststellt, dass die Eingabedatei eine Binärdatei ist, kann es anstelle von übereinstimmenden Zeilen die Meldung anzeigen. Wenn Sie sicher sind, dass es sich tatsächlich um eine Textdatei handelt, können Sie sie mit -a als Text behandeln.
grep -a 'ERROR' mixed-data.log
Umgekehrt können Sie, um Binärdateien bei rekursiven Suchen auszuschließen, -I verwenden. Verwenden Sie -a nicht immer bei unbekannten Binärdaten, da diese Steuerzeichen enthalten können, die Ihr Terminal durcheinanderbringen.
Wenn Ergebnisse aufgrund von Regex-Sonderzeichen abweichen
Der Punkt entspricht in regulären Ausdrücken einem einzelnen Zeichen und das Sternchen bedeutet Wiederholung des vorangehenden Ausdrucks. Wenn Sie beabsichtigten, nach einer einfachen Zeichenkette zu suchen, verwenden Sie -F, und wenn Sie einen regulären Ausdruck verwenden möchten, setzen Sie das gesamte Muster in einfache Anführungszeichen, um die Shell-Erweiterung zu verhindern.
Wenn rekursive Suchvorgänge zu langsam sind oder zu viele Ergebnisse liefern
Begrenzen Sie das Startverzeichnis für die Suche und schließen Sie unnötige Dateien mithilfe von --include, --exclude und --exclude-dir aus. Um nur Berechtigungsfehler zu verbergen, könnten Sie versucht sein, alle Standardfehler zu verwerfen, aber dies kann dazu führen, dass wichtige Probleme übersehen werden. Daher ist es besser, zunächst den Suchbereich und die Dateiberechtigungen zu überprüfen.
Häufig gestellte Fragen
Unterscheidet grep standardmäßig zwischen Groß- und Kleinbuchstaben?
Ja. Die Standardsuche ist case-sensitiv. Um die Groß-/Kleinschreibung zu ignorieren, verwenden Sie -i. Sie sollten auch berücksichtigen, dass das Ergebnis der Groß-/Kleinschreibung je nach Gebietsschema variieren kann.
Was ist der Unterschied zwischen grep -r und grep -R?
In GNU grep führen beide rekursive Suchen durch, aber -R folgt allen symbolischen Links, die während der Suche angetroffen werden. Für typische Quellcode- oder Konfigurationsdateisuche ist -r leichter vorhersehbar.
Ist es ein Fehler, wenn keine Suchergebnisse gefunden werden?
Nicht unbedingt. Wenn es keine Treffer gibt, gibt es normalerweise einen Exit-Status von 1 zurück, während Fehler wie Datei-Zugriffsfehler oder ungültige Optionen durch den Status 2 unterschieden werden.
Wie finde ich Zeilen, die mindestens einen von mehreren Suchbegriffen enthalten?
grep -E 'error|warning' filename verwendet den Alternationsoperator in erweiterten regulären Ausdrücken, oder Sie können -e wie grep -e 'error' -e 'warning' filename wiederholen. Um den Suchbegriff als normalen String und nicht als regulären Ausdruck zu behandeln, können Sie auch -F verwenden.
Zusammenfassung
Für allgemeine String-Suchen ist es gut, sich mit grep -F vertraut zu machen; für mehrere reguläre Ausdrucksbedingungen, grep -E; und für die Suche in einem gesamten Verzeichnis, grep -r. Um die Ergebnisse leichter interpretierbar zu machen, können Sie -n und -C verwenden; wenn Sie nur die Dateiliste benötigen, verwenden Sie -l; und um das Vorhandensein in Skripten zu prüfen, verwenden Sie -q.
Muster in einfache Anführungszeichen setzen, den Umfang rekursiver Suchen speziell begrenzen und zwischen Exit-Status 1 und Fehlerstatus 2 unterscheiden – dies sind die Schlüssel für eine sichere Nutzung. Um andere grundlegende Werkzeuge gemeinsam zu erkunden, siehe eine Liste häufig verwendeter Linux-Befehle.




