Grep: Unterschied zwischen den Versionen
K Textersetzung - „Linux:Befehl“ durch „Linux/Befehl“ |
K Textersetzung - „ “ durch „ “ |
||
(5 dazwischenliegende Versionen desselben Benutzers werden nicht angezeigt) | |||
Zeile 4: | Zeile 4: | ||
<br> | <br> | ||
<code>grep</code> steht für '''G'''lobal ''''R'''egular '''E'''xpression '''P'''rint. | <code>grep</code> steht für '''G'''lobal ''''R'''egular '''E'''xpression '''P'''rint. | ||
Das heisst, dass du auch Regular Expressions für die Suche nutzen kannst. Wenn du noch nicht weisst, was Regular Expressions sind, solltest du dir ein | Das heisst, dass du auch Regular Expressions für die Suche nutzen kannst. Wenn du noch nicht weisst, was Regular Expressions sind, solltest du dir ein Regular expression-Tutorial anschauen. Empfehlenswert ist zum Beispiel das interaktive von regexone.com. Ohne Regular expressiones ist grep aber natürlich auch nutzbar.<br> | ||
=Installation= | =Installation= | ||
Zeile 45: | Zeile 45: | ||
Ein zweites Einsatzgebiet ist die Verwendung als Zeilen-Filter innerhalb einer Kette von Befehlen, z. B.:<br> | Ein zweites Einsatzgebiet ist die Verwendung als Zeilen-Filter innerhalb einer Kette von Befehlen, z. B. :<br> | ||
Zeile 201: | Zeile 201: | ||
* Wiki-Ubuntuuseres : https://wiki.ubuntuusers.de/grep/ | * Wiki-Ubuntuuseres : https://wiki.ubuntuusers.de/grep/ | ||
[[Kategorie:Linux | [[Kategorie:Linux/Suchen]] | ||
[[Kategorie:Linux/Befehl]] | [[Kategorie:Linux/Befehl]] | ||
{{DEFAULTSORT:grep}} | {{DEFAULTSORT:grep}} | ||
Zeile 232: | Zeile 232: | ||
* <tt>-P --perl-regexp</tt> | * <tt>-P --perl-regexp</tt> | ||
In anderen Implementierungen entspricht das z.B. den drei Kommandos egrep, grep und fgrep (ohne PCRE). | In anderen Implementierungen entspricht das z. B. den drei Kommandos egrep, grep und fgrep (ohne PCRE). | ||
== grep vs egrep == | == grep vs egrep == | ||
Zeile 412: | Zeile 412: | ||
= Reguläre Ausdrücke = | = Reguläre Ausdrücke = | ||
Ein regulärer Ausdruck (engl. regular expression, Abk. RegExp oder | Ein regulärer Ausdruck (engl. regular expression, Abk. RegExp oder Regular expression) eine Zeichenkette, die der Beschreibung von Mengen beziehungsweise Untermengen von Zeichenketten mit Hilfe bestimmter syntaktischer Regeln dient. | ||
Zeile 475: | Zeile 475: | ||
Dabei gibt es zwei Varianten, die Optionen anzugeben. Diese Varianten gibt es bei den meisten Linux-Befehlen: | Dabei gibt es zwei Varianten, die Optionen anzugeben. Diese Varianten gibt es bei den meisten Linux-Befehlen: | ||
# die Kurzform, ein Minuszeichen und direkt dahinter der Optionsbuchstabe. Bsp: -c | # die Kurzform, ein Minuszeichen und direkt dahinter der Optionsbuchstabe. Bsp: -c | ||
# Vorteile: kürzer, und bei dieser Form kannst du auch gleich mehrere Optionen hintereinander klemmen, z.B. -ciw | # Vorteile: kürzer, und bei dieser Form kannst du auch gleich mehrere Optionen hintereinander klemmen, z. B. -ciw | ||
# die Langform, zwei Minuszeichen und der Optionsname ausgeschrieben. Bsp: –count | # die Langform, zwei Minuszeichen und der Optionsname ausgeschrieben. Bsp: –count | ||
== | == Regular expression Syntax == | ||
Sollen ERE genutzt werden, +, ?, | und (), muss der Parameter -E angegebenen werden. | Sollen ERE genutzt werden, +, ?, | und (), muss der Parameter -E angegebenen werden. | ||
Zeile 570: | Zeile 570: | ||
== Trefferanzahl anzeigen == | == Trefferanzahl anzeigen == | ||
Die Anzahl aller Zeilen, die das Suchmuster beinhalten, kannst du dir mit -c oder –count ausgeben lassen. Damit liefert grep die reine Anzahl, also z.B. “4″ für 4 Treffer zurück, sonst nichts. | Die Anzahl aller Zeilen, die das Suchmuster beinhalten, kannst du dir mit -c oder –count ausgeben lassen. Damit liefert grep die reine Anzahl, also z. B. “4″ für 4 Treffer zurück, sonst nichts. | ||
== -c == | == -c == | ||
Zeile 643: | Zeile 643: | ||
grep -E '([a-zA-Z0-9_\-\.]+)@([a-zA-Z0-9_\-\.]+)\.([a-zA-Z]{2,5})' datei.txt | grep -E '([a-zA-Z0-9_\-\.]+)@([a-zA-Z0-9_\-\.]+)\.([a-zA-Z]{2,5})' datei.txt | ||
Den | Den Regular expression ohne die einfachen Anführungsstriche in eine Datei schreiben: | ||
echo '([a-zA-Z0-9_\-\.]+)@([a-zA-Z0-9_\-\.]+)\.([a-zA-Z]{2,5})' > \ ~/snippets/regexes/email | echo '([a-zA-Z0-9_\-\.]+)@([a-zA-Z0-9_\-\.]+)\.([a-zA-Z]{2,5})' > \ ~/snippets/regexes/email | ||
Nun kannst du den | Nun kannst du den Regular expression im obigen Beispiel mit dem File ersetzen: | ||
grep -Ef ~/snippets/regexes/email datei.txt | grep -Ef ~/snippets/regexes/email datei.txt | ||
Zeile 653: | Zeile 653: | ||
'''Tipp''' | '''Tipp''' | ||
Mach es dir zur Gewohnheit, immer alle | Mach es dir zur Gewohnheit, immer alle Regular expressiones, die du verwendest, unter einem aussagekräftigen Dateinamen in einem bestimmten Verzeichnis zu speichern. So sammelst du mit der Zeit ein komfortables, wiederverwendbares Regular expression-Kompendium. | ||
= Beispiele = | = Beispiele = | ||
Zeile 924: | Zeile 924: | ||
Bei der Systemadministration fragt man sich häufig, in welcher Datei eigentlich welche Shell-Variable gesetzt wird? Die globalen Vorgaben erfolgen zum Großteil in den Dateien des Verzeichnisses /etc. | Bei der Systemadministration fragt man sich häufig, in welcher Datei eigentlich welche Shell-Variable gesetzt wird? Die globalen Vorgaben erfolgen zum Großteil in den Dateien des Verzeichnisses /etc. | ||
== Namen der Dateien, in denen z.B. die PATH-Variable modifiziert wird == | == Namen der Dateien, in denen z. B. die PATH-Variable modifiziert wird == | ||
grep -l PATH /etc/* 2>/dev/null | grep -l PATH /etc/* 2>/dev/null |
Aktuelle Version vom 28. Mai 2023, 08:06 Uhr
Bedeutung
grep
steht für Global 'Regular Expression Print.
Das heisst, dass du auch Regular Expressions für die Suche nutzen kannst. Wenn du noch nicht weisst, was Regular Expressions sind, solltest du dir ein Regular expression-Tutorial anschauen. Empfehlenswert ist zum Beispiel das interaktive von regexone.com. Ohne Regular expressiones ist grep aber natürlich auch nutzbar.
Installation
Das Programm grep ist im essentiellen Paket
# apt install grep
von Linux enthalten und ist deshalb auf jedem System installiert.
Aufruf von grep
grep [Optionen] [-e Muster | -f Datei] [Datei...]
außerdem gibt es noch drei Varianten von grep:
egrep entspricht grep -E (obige Beschreibung von regular expressions bezog sich auf diese Variante)
fgrep entspricht grep -F
rgrep entspricht grep -r
Einsatzgebiete
grep wird in erster Linie dann eingesetzt, wenn Dateien durchsucht werden müssen, zum Beispiel die Quelldateien eines Computerprogramms oder Logdateien. In Zusammenarbeit mit find kann ein ganzer Dateibaum gelesen werden.
$ find /home/benutzername -exec grep -H "Passwort" {} \;
Dieses Kommando durchsucht alle Dateien des Quellverzeichnisses des Benutzers benutzername nach der Zeichenkette Passwort und zeigt die gefundenen Zeilen zusammen mit dem Dateinamen an, wobei die Anzeige des Dateinamens durch die Option -H ausgelöst wird.
Manche grep-Versionen ermöglichen eine kürzere Formulierung mit Hilfe der Option -r:
$ grep -r "Passwort" /home/benutzername
Ein zweites Einsatzgebiet ist die Verwendung als Zeilen-Filter innerhalb einer Kette von Befehlen, z. B. :
$ tail -1000 /var/log/mail | grep "Mailadresse"
Parameter
Diese Parameterliste ist unvollständig. Weiteres findet sich auf der man-Seite von grep
Kurzform | Langform | Beschreibung |
---|---|---|
-A NUM | --after-context=NUM | gibt zusätzlich NUM Zeilen nach der passenden Zeile aus. |
-a text | --text | Verarbeite eine binäre Datei, als wäre sie Text. Dies entspricht der Option --binary-files=text. |
-B NUM | --before-context=NUM Beispiel | gibt zusätzlich NUM Zeilen vor der passenden Zeile aus. |
-b | --byte-offset | gibt den Byte-Offset innerhalb der Datei vor jeder gefundenen Zeile an. |
-c | --binary-files=TYP | gibt an, wie grep mit binären Dateien verfahren soll. Default für Typ ist binary, in diesem Fall gibt grep nur eine kurze einzeilige Mitteilung aus, ob die Datei das Muster enthält oder nicht. without-match nimmt an, dass eine binäre Datei keine passenden Zeichenketten enthält. Bei text verarbeitet grep die Datei als wäre sie eine Textdatei. Vorsicht: Die Ausgabe von binären Daten kann zu unerwünschten Resultaten führen, wenn die Ausgabe auf einem Terminal erfolgt, und dieses einige der Zeichenketten als Befehle interpretiert! |
-C NUM | --count | unterdrückt die normale Ausgabe und gibt stattdessen für jede Eingabedatei an, wieviele Zeilen auf die regular expression passen. |
--colour[=Wann], --color[=Wann] | Markiert Treffer farbig. Wann kann dabei "never", "always" oder "auto" sein. | |
-F | --fixed-strings | interpretiert das übergebene Muster als eine Liste von festen Zeichenketten, die durch Zeilenumbrüche voneinander getrennt sind. |
-f Datei | --file=Datei | beziehe die Muster aus Datei, eines je Zeile. Eine leere Datei enthält keine Muster und passt somit auf keinen String. |
-H | --with-filename | gibt den Dateinamen vor jedem Treffer aus |
-I | --binary-files=without-match | schließt Binärdateien aus. |
-i | --ignore-case | unterscheide nicht zwischen Groß- und Kleinschreibung. |
-L | --files-without-match | unterdrückt die normale Ausgabe und gibt stattdessen die Dateinamen von allen Dateien, die keine Treffer enthalten aus. Die Bearbeitung stoppt, sobald ein Treffer auftritt. |
-l | --files-with-match | unterdrückt die normale Ausgabe und gibt stattdessen die Dateinamen von allen Dateien, die Treffer enthalten aus. Die Bearbeitung stoppt, sobald ein Treffer auftritt. |
-n | --line-number | gibt die Zeilennummer vor jedem Treffer aus. |
-v | --invert-match | Invertiert die Suche und liefert alle Zeilen die nicht auf das gesuchte Muster passen. |
Regular Expressions
Listen (bracket expressions)
Erwartet man an einer Stelle innerhalb des Regulären Ausdrucks nicht ein ganz bestimmtes Zeichen, sondern nur eines aus einer spezifischen Liste, so kann man dies durch eine sogenannte bracket expression ausdrücken. Die Liste der Zeichen, aus der das zu findende Zeichen stammen soll, wird dazu einfach in eckigen Klammern "[]" angegeben. Um beispielsweise alle Buchstaben "a", egal ob groß oder klein, zu finden, verwendet man folgenden regulären Ausdruck: "[Aa]" Möchte man alle Zeichen finden, die nicht in der Liste stehen, die Liste also negieren, so muss das erste Zeichen in der Liste ein Caret "^" sein. Ein regulärer Ausdruck der Form "[^Aa]" passt also auf alle Zeichen, die weder ein großes "A" noch ein kleines "a" sind.
Kurzes Beispiel: "[Aa]lpha" findet alle Textstücke "Alpha" und "alpha".
Um die Listen der bracket extensions kompakt darstellen zu können, werden range expressions verwendet. Ein range expression wird durch zwei Zeichen, die durch einen Bindestrich miteinander verbunden sind, dargestellt: "[a-d]". Ein solcher Ausdruck passt auf alle Zeichen, die in der Sortierung des Zeichensatzes zwischen die beiden Zeichen fallen. Leider hängt diese Sortierung von der verwendeten locale-Einstellung ab. In der Standard C locale würde obiges Muster "[a-d]" einem regulären Ausdruck von "[abcd]" entsprechen, während er bei vielen anderen locales einem Ausdruck "[aBbCcDd]" entsprechen würde. Um die C locale für die Zeichensortierung zu erzwingen, kann man der Variablen LC_CTYPE den Wert C zuweisen:
LC_CTYPE=C befehl | gilt nur für diesen Befehl |
LC_CTYPE=C grep -E [a-d] Datei | Beispiel |
export LC_CTYPE=C | gilt für alle nachfolgenden Befehle |
Die meisten Zeichen mit besonderer Bedeutung verlieren diese Bedeutung innerhalb eines bracket expressions. Um ein Zeichen "]" in die Liste aufzunehmen, muss es an der ersten Stelle in der Liste stehen. Um das Caret "^" in die Liste aufzunehmen, kann es irgendwo in der Liste stehen, nur nicht an der ersten Stelle. Um den Bindestrich "-" in die Liste einzufügen, muss es an letzter Stelle stehen.
Darüber hinaus gibt es einige vordefinierte Listen:
- [:alnum:] alle Ziffern und Buchstaben
- [:alpha:] alle Buchstaben
- [:cntrl:] alle Kontrollzeichen
- [:digit:] alle Ziffern
- [:lower:] alle Kleinbuchstaben
- [:punct:] alle Satzzeichen
- [:blank:] Leerzeichen
- [:space:] Zeichen die Leerraum erzeugen (Leerzeichen, Zeilenvorschub, ...)
- [:upper:] alle Großbuchstaben
Besondere Zeichen
Der Punkt "." passt auf ein beliebiges Zeichen.
Das Caret "^" findet den Anfang einer Zeile.
Das Dollarzeichen "$" findet das Ende einer Zeile.
Die Symbole "\<" passen auf den Beginn eines Wortes.
Die Symbole "\>" passen auf das Ende eines Wortes.
Wiederholungsoperatoren
Reguläre Ausdrücke können mit Hilfe dieser Operatoren öfter wiederholt werden.
"?" Der vorangegangene Ausdruck ist Optional und wird maximal einmal angetroffen.
"*" Der vorangegangene Ausdruck wird beliebig oft (auch keinmal) vorgefunden.
"+" Der vorangegangene Ausdruck wird mindestens einmal gefunden.
"{n}" Der vorangegangene Ausdruck wird genau n-mal gefunden.
"{n,}" Der vorangegangene Ausdruck wird mindestens n-mal oder öfter angetroffen.
"{n,m}" Der vorangegangene Ausdruck wird mindesten n-mal und maximal m-mal angetroffen.
Zusammenführung von regulären Ausdrücken
Mehrere reguläre Ausdrücke können durch Aneinanderfügen zusammengeführt werden. Ein solcher Ausdruck findet dann alle Zeichenketten, die aneinander gehängt zu dem jeweiligen Ausdruck passen. Das obige Beispiel "[Aa]lpha" stellt eine solche Verkettung dar. Es ist aus den Einzelnen Bausteinen "[Aa]", "l", "p", "h" und "a" aufgebaut.
Verknüpfung durch "oder"
Durch den Operator "|" lassen sich reguläre Ausdrücke mit einem "oder" verknüpfen. Der daraus entstehende Ausdruck findet Zeichenketten, die entweder auf den einen oder den anderen Ausdruck passen.
Kurzes Beispiel: "[Aa]lpha|[Bb]ravo" findet alle Textstücke "Alpha", "alpha", "Bravo" und "bravo" (am Besten nur mit Parameter -E oder egrep).
Vorrang der Regeln
Ähnlich wie bei mathematischen Ausdrücken (Punkt- vor Strichrechnung) unterliegen die Verknüpfungsoperatoren einer gewissen Rangfolge: Wiederholungen kommen vor Verkettungen, die wiederum vor dem "oder" kommen. Wie auch in arithmetischen Ausdrücken lassen sich diese Regeln durch Klammern überschreiben.
Geklammerte Ausdrücke referenzieren
Eine Teilzeichenkette, die auf einen geklammerten Teilausdruck gepasst hat, lässt sich durch "\n" referenzieren. Dabei steht "n" für eine einzelne Ziffer, die den n-ten geklammerten Teilausdruck auswählt.
Beispiele:
- "\<[Aa]+n+[ae]+\>" findet alle Wörter, die ungefähr wie Anne oder Anna aussehen, nur mit beliebig vielen "A", "n" und "e" (sofern sie jeweils mindestens ein mal vorkommen). AAnnneeea würde zum Beispiel auch passen.
- "[Ss]up(er|ra)" findet alle Wörter, die ein Super, super, Supra oder supra enthalten.
- "^digit:" findet alle Zeilen, die mit einer Ziffer beginnen.
Quellen
- Wiki-Ubuntuuseres : https://wiki.ubuntuusers.de/grep/
TMP
grep schreibt alle Zeilen der Eingabe, die das gesuchte Muster enthalten, auf die Standardausgabe.
Einführung
Mit get regularexpression lassen sich Dateien nach bestimmten Textstücken durchsuchen. Die Suchmuster werden regular expressions genannt. Sie sind vielfältig einsetzbar, und werden nicht nur von grep verwendet.
»Global search for a regular expression and print out matched lines«
kurz 'g/re/p' ist das gebräuchlichste Kommando, um in Dateien nach bestimmten Mustern zu suchen.
Syntax
grep [Optionen] Muster [Datei...]
oder
grep [Optionen] [-e Muster | -f Datei] [Datei...]
Einsatz als Filter
Die Eingabe kann über die Standardeingabe oder die Angabe von Dateien erfolgen.
cat /etc/services | grep MySQL
GNU Grep unterstützt
- -G --basic-regexp, (BRE)
- -E --extended-regexp (ERE)
- -F --fixed-strings
- -P --perl-regexp
In anderen Implementierungen entspricht das z. B. den drei Kommandos egrep, grep und fgrep (ohne PCRE).
grep vs egrep
egrep is the same as grep -E. It interpret PATTERN as an extended regular expression.
From the grep man page:
In basic regular expressions the meta-characters ?, +, {, |, (, and ) lose their special meaning; instead use the backslashed versions \?, \+, \{, \|, \(, and \). Traditional egrep did not support the { meta-character, and some egrep implementations support \{ instead, so portable scripts should avoid { in grep -E patterns and should use [{] to match a literal {. GNU grep -E attempts to support traditional usage by assuming that { is not special if it would be the start of an invalid interval specification. For example, the command grep -E '{1' searches for the two-character string {1 instead of reporting a syntax error in the regular expression. POSIX.2 allows this behavior as an extension, but portable scripts should avoid it.
egrep oder grep -E?
Extended Grep (erweitertes grep) versteht andere Regulären Ausdrücke als »grep«.
egrep ist wie grep, nur mit dem Unterschied, dass auch +, ?, | und () als Regular Expression genutzt werden können.
egrep ist nichts anderes als ein grep -E. Auf vielen Maschinen ist egrep sogar nur ein Link auf grep. Außerdem ist egrep veraltet, weswegen grep -E genutzt werden sollte.
fgrep
Fgrep kann immer anstelle von grep verwendet werden, falls das zu suchende Muster keine regulären Ausdrücke enthält.
Alle Sonderzeichen in der Musterzeichenkette verlieren ihre Sonderbedeutung und werden als Bestandteil des Musters verstanden. Fgrep arbeitet dadurch etwas schneller als grep und ist vor allem beim Durchsuchen großer Datenmengen nützlich.
Effizientz
Grep arbeitet bei der Suche wesentlich effizienter als das in einem Editor geschehen würde.
Parameterübersicht
Mit grep lassen sich Zeichenketten in Dateien finden, die auf die angegebenen regular expressions passen. Wird keine Datei angegeben, so wird die Standardeingabe verwendet.
Diese Parameterliste ist unvollständig. Weiteres findet sich auf der man-Seite von grep.
Kurzform | Langform | Beschreibung |
-A NUM | --after-context=NUM | gibt zusätzlich NUM Zeilen nach der passenden Zeile aus. |
-a text | --text | Verarbeite eine binäre Datei, als wäre sie Text. Dies entspricht der Option --binary-files=text. |
-B NUM | --before-context=NUM | gibt zusätzlich NUM Zeilen vor der passenden Zeile aus. |
-b | --byte-offset | gibt den Byte-Offset innerhalb der Datei vor jeder gefundenen Zeile an. |
--binary-files=TYP | gibt an, wie grep mit binären Dateien verfahren soll. Default für Typ ist binary, in diesem Fall gibt grep nur eine kurze einzeilige Mitteilung aus, ob die Datei das Muster enthält oder nicht. without-match nimmt an, dass eine binäre Datei keine passenden Zeichenketten enthält.
Bei text verarbeitet grep die Datei als wäre sie eine Textdatei. Vorsicht: Die Ausgabe von binären Daten kann zu unerwünschten Resultaten führen, wenn die Ausgabe auf einem Terminal erfolgt, und dieses einige der Zeichenketten als Befehle interpretiert! | |
-C NUM | --context=NUM | gibt zusätzlich NUM Zeilen von Kontext aus. Zwischen zusammenhängende Gruppen von Treffern werden Zeilen mit "--" eingefügt. |
-c | --count | unterdrückt die normale Ausgbabe und gibt stattdessen für jede Eingabedatei an, wieviele Zeilen auf die regular expression passen. |
--colour[=Wann], --color[=Wann] | Markiert Treffer farbig. Wann kann dabei "never", "always" oder "auto" sein. | |
-E | --extended-regexp | Verwendet die extended Variante beim Interpretieren der übergebenen regular expression. |
-e Muster | --regexp=Muster | verwende Muster als regular expression. Nützlich um Ausdrücke zu schützen, die mit einem - beginnen. |
-F | --fixed-strings | interpretiert das übergebene Muster als eine Liste von festen Zeichenketten, die durch Zeilenumbrüche voneinander getrennt sind. |
-f Datei | --file=Datei | beziehe die Muster aus Datei, eines je Zeile. Eine leere Datei enthält keine Muster und passt somit auf keinen String. |
-H | --with-filename | gibt den Dateinamen vor jedem Treffer aus. |
-h | --no-filename | unterdrückt die Ausgabe des Dateinamens, wenn mehrere Dateien durchsucht werden. |
-I | --binary-files=without-match | schließt Binärdateien aus. |
-i | --ignore-case | unterscheide nicht zwischen Groß- und Kleinschreibung. |
-L | --files-without-match | unterdrückt die normale Ausgabe und gibt stattdessen die Dateinamen von allen Dateien, die keine Treffer enthalten aus. Die Bearbeitung stoppt, sobald ein Treffer auftritt. |
-l | --files-with-match | unterdrückt die normale Ausgabe und gibt stattdessen die Dateinamen von allen Dateien, die Treffer enthalten aus. Die Bearbeitung stoppt, sobald ein Treffer auftritt. |
-n | --line-number | gibt die Zeilennummer vor jedem Treffer aus. |
-o | --only-matching | gibt nur die passende Zeichenkette aus. |
-P | --perl-regexp | verwendet Perl regular expressions. |
-q | --quiet, --silent | schreibt nichts auf die Standardausgabe und stoppt beim ersten Treffer. |
-R -r | --recursive | liest alle Dateien unter jedem Verzeichnis rekursiv. |
-v | --invert-match | Invertiert die Suche und liefert alle Zeilen die nicht auf das gesuchte Muster passen. |
-w | --word-regexp | wählt nur solche Zeilen aus, deren Treffer aus vollständigen Wörtern bestehen.
|
Rückgabewerte
Zudem liefern die Kommandos der Grep-Familie einen Rückgabewert an das Betriebssystem, was sie für die Verwendung in Shellprogrammen prädestiniert.
Häufig interessiert man sich nicht für den exakten Inhalt der Zeile, die das Muster enthält, sondern einzig ob das Muster überhaupt existiert.
Vor allem in Shellskripten wird man die Ausgaben der Kommandos unterdrücken und anschließend anhand des Rückgabewertes den weiteren Programmablauf steuern.
Rückgabewert 0
Muster wurde gefunden
# "root" sollte es in jeder "passwd" geben grep root /etc/passwd >& /dev/null echo $? 0
Rückgabewert 1
Muster wurde nicht gefunden
# "ROOT" gibt es hoffentlich nicht grep ROOT /etc/passwd >& /dev/null echo $? 1
Rückgabewert 2
Datei nicht gefunden
# die Datei "/bla" gibt es nicht grep text /bla >& /dev/null echo $? 2
Reguläre Ausdrücke
Ein regulärer Ausdruck (engl. regular expression, Abk. RegExp oder Regular expression) eine Zeichenkette, die der Beschreibung von Mengen beziehungsweise Untermengen von Zeichenketten mit Hilfe bestimmter syntaktischer Regeln dient.
Funktion | |
^ | Beginn der Zeile |
$ | Ende der Zeile |
. | Genau ein beliebiges Zeichen |
* | Beliebig viele des vorangegangenen Zeichens |
[:zeichenklasse:] | Ein Zeichen aus dem Bereich. Anstelle von Zeichen können vordefinierte Klassen von Zeichen verwendet werden: [:alnum:], [:alpha:], [:cntrl:], [:digit:], [:graph:], [:lower:], [:print:], [:punct:], [:space:], [:upper:], und [:xdigit:]. |
[^] | Kein Zeichen aus dem Bereich |
\< | Muster am Wortanfang suchen |
\> | Muster am Wortende suchen |
\(..\) | Eingeschlossenes Muster vormerken; auf dieses kann später über \1 zugegriffen werden. Bis zu neun Muster können auf diese Weise gespeichert werden |
x\{m\} | m-faches Auftreten des Zeichens x |
x\{m,n\} | mindestens m-, maximal n-maliges Auftreten des Zeichens x |
+ | Mindestens ein Auftreten des vorangegangenen Zeichens |
? | Höchstens ein Auftreten des vorangegangenen Zeichens |
x|y | Zeichen "x" oder Zeichen "y" |
(abc|xyz) | Zeichenkette "abc" oder Zeichenkette "xyz". Die runden Klammern können entfallen.
|
Optionen
Mittels verschiedener Optionen kannst du das Verhalten und die Ausgabe von grep verändern.
Schreibweisen
Dabei gibt es zwei Varianten, die Optionen anzugeben. Diese Varianten gibt es bei den meisten Linux-Befehlen:
- die Kurzform, ein Minuszeichen und direkt dahinter der Optionsbuchstabe. Bsp: -c
- Vorteile: kürzer, und bei dieser Form kannst du auch gleich mehrere Optionen hintereinander klemmen, z. B. -ciw
- die Langform, zwei Minuszeichen und der Optionsname ausgeschrieben. Bsp: –count
Regular expression Syntax
Sollen ERE genutzt werden, +, ?, | und (), muss der Parameter -E angegebenen werden.
Unterverzeichnisse durchsuchen
-r
(recursive) durchsucht Unterverzeichnisse
NICHT betroffene Zeilen anzeigen
-v
Zeigt alle Zeilen an, die das Muster nicht enthalte
ohne -v
$ ps ax | grep inetd 133 ? S 0:00 /usr/sbin/inetd 762 pts/2 S 0:00 grep inetd
die Ausgabe "grep" herausfiltern
ps ax | grep inetd | grep -v grep 133 ? S 0:00 /usr/sbin/inetd
Groß- und Kleinschreibung ignorieren
Standardmässig sucht der grep-Befehl case-sensitive, das heisst, die Groß- und Kleinschreibung wird beachtet. Willst du ohne dies, also case-insensitive, suchen, musst du die Option -i hinzufügen.
-i
Groß- und Kleinschreibung werden nicht unterschieden
$ grep -i ROot /etc/passwd root:x:0:0:root:/root:/bin/bash
Einziger Inhalt
-x
Findet Zeilen, die den Suchstring als einzigen Inhalt haben
Nur ganze Wörter finden
Per default findet grep alle Vorkommen des Suchstrings, sowohl in Wortteilen als auch ganzen Wörten. Nur auf Vorkommen in ganzen Wörtern beschränkst du per -w.
-w
Das Suchmuster muss ein einzelnes Wort sein (also kein Bestandteil eines anderen Wortes)
echo -e "Automaten\n essen\n keine Tomaten" | grep -i Tomaten Automaten keine Tomaten echo -e "Automaten\n essen\n keine Tomaten" | grep -iw Tomaten keine Tomaten
Ausgabe anpassen
Treffer einfärben
Standardmäßig ist die Ausgabe von grep farblos. Für die Übersichtlichkeit ist es hilfreich, wenn du das gematchte Pattern in jeder Zeile farblich hervorhebst.
--color
Hebt Treffer farblich hervor
Per default
--color // bashrc alias?
Ich habe das per Default in meiner .bashrc/.zshrc. Wenn du dies auch willst, musst du nur die Zeile
export GREP_OPTIONS='--color=auto'
in deiner Shell-Config-File einfügen. Falls dir die Farbe nicht gefällt, kannst du sie per
export GREP_COLOR='1;32'
nach Belieben ändern. Für eine andere Farbe einfach einen der Farbcodes in den Hochkommata ersetzen.
Black 0;30 Dark Gray 1;30 Blue 0;34 Light Blue 1;34 Green 0;32 Light Green 1;32 Cyan 0;36 Light Cyan 1;36 Red 0;31 Light Red 1;31 Purple 0;35 Light Purple 1;35 Brown 0;33 Yellow 1;33 Light Gray 0;37 White 1;37
Trefferanzahl anzeigen
Die Anzahl aller Zeilen, die das Suchmuster beinhalten, kannst du dir mit -c oder –count ausgeben lassen. Damit liefert grep die reine Anzahl, also z. B. “4″ für 4 Treffer zurück, sonst nichts.
-c
Anzeige der Anzahl Zeilen, in denen das Muster gefunden wurde
$ grep -c bash /etc/passwd 38
Zeilennummer anzeigen
Sinnvoll vor allem bei Sourcecode-Dateien ist die Option -n. Wenn du dem grep-Befehl diese Option mitgibst, wird vor jedes Match die Zeilennummer des Matches geschrieben.
-n
Zeigt die Zeilennummer an, in der das Muster gefunden wurde
$ grep -n root /etc/passwd 1:root:x:0:0:root:/root:/bin/bash
Nur Dateinamen ausgeben lassen
Manchmal braucht man nur den/die Dateinamen, in denen der Suchstring gefunden wurde. Das kannst du über die Option -l (kleines “L”) erreichen.
-l
Nur Anzeige der Namen der Dateien, in denen das Muster gefunden wurde
$ grep -l tcp /etc/host* /etc/hosts.allow /etc/hosts.deny
Dateinamen ohne Treffer
-L
Auch gibt es Anwendungsfälle, in denen du nur die Dateinamen aufgelistet haben willst, in denen der Suchstring NICHT gefunden wurde. Dafür nutzt du die Option -L.
Kontext anzeigen
-A [Anzahl]
Zeigt Anzahl Zeilen an, die der Zeile mit dem Muster folgen
grep -A 2 root /etc/passwd root:x:0:0:root:/root:/bin/bash bin:x:1:1:bin:/bin:/bin/bash daemon:x:2:2:daemon:/sbin:/bin/bash
-B [Anzahl]
Zeigt Anzahl Zeilen an, die vor der Zeile mit dem Muster liegen
-C [Anzahl]
Anzahl Zeilen vor- und nach dem Treffer
Ausgabe unterdrücken
-s
Unterdrückt die Fehlerausgaben (Standardfehler); sinnvoll in Skripten
Muster aus Datei laden
Wer komplexer Suchmuster immer wieder verwendet, kann diese in Dateien speichern und im grep-Befehl per -f regexdatei einbinden.
Beispiel
alle Zeilen mit Emailadressen aus einer Datei filtern
grep -E '([a-zA-Z0-9_\-\.]+)@([a-zA-Z0-9_\-\.]+)\.([a-zA-Z]{2,5})' datei.txt
Den Regular expression ohne die einfachen Anführungsstriche in eine Datei schreiben:
echo '([a-zA-Z0-9_\-\.]+)@([a-zA-Z0-9_\-\.]+)\.([a-zA-Z]{2,5})' > \ ~/snippets/regexes/email
Nun kannst du den Regular expression im obigen Beispiel mit dem File ersetzen:
grep -Ef ~/snippets/regexes/email datei.txt
Tipp
Mach es dir zur Gewohnheit, immer alle Regular expressiones, die du verwendest, unter einem aussagekräftigen Dateinamen in einem bestimmten Verzeichnis zu speichern. So sammelst du mit der Zeit ein komfortables, wiederverwendbares Regular expression-Kompendium.
Beispiele
Grafikkarte ausgeben
lspci | grep VGA
“foobar” am Anfang finden
in datei1.txt UND datei2.txt
grep '^foobar' datei1.txt datei2.txt
Leerzeilen finden
grep '^$' file.php
Zeilen mit “ein”, als ganzes Wort
nicht “Bein” oder “einziehen”
grep -w 'ein' datei.txt
Zeige alle HDDs an
dmesg | grep -E '(s|h)d[a-z]'
Liste alle mysql Prozesse auf
ps aux | grep mysql
Reguläre Ausdrücke in grep
Unter Linux wird GNU grep genutzt, dass Erweiterte Reguläre ausdrücke unterstüzt. GNU grep standard auf allen Linux-Systemen.
Reguläre Ausdrücke
Ein Regulärer Ausdruck ist nichts als ein Muster dass auf für jede Eingabezeile zutreffen soll. Ein Muster ist eine Reihe von Zeichen. Hier einige Beispiele:
^w1 w1|w2 [^ ]
Reguläre Ausdrücke für grep
Suche nach 'vivek' in /etc/passswd
grep vivek /etc/passwd
Beispielausgabe:
vivek:x:1000:1000:Vivek Gite,,,:/home/vivek:/bin/bash vivekgite:x:1001:1001::/home/vivekgite:/bin/sh gitevivek:x:1002:1002::/home/gitevivek:/bin/sh
Suche in Groß- und Kleinschreibung
grep -i -w vivek /etc/passwd
Suche nach 'vivek' oder 'raj' in Groß- und Kleinschreibung
grep -E -i -w 'vivek|raj' /etc/passwd
Das MUSTER in diesem Beispiel nutzt extended regular expression.
Anker
You can use ^ and $ to force a regex to match only at the start or end of a line, respectively. The following example displays lines starting with the vivek only:
grep ^vivek /etc/passwd
Sample outputs:
vivek:x:1000:1000:Vivek Gite,,,:/home/vivek:/bin/bash vivekgite:x:1001:1001::/home/vivekgite:/bin/sh
You can display only lines starting with the word vivek only i.e. do not display vivekgite, vivekg etc:
grep -w ^vivek /etc/passwd
Find lines ending with word foo:
grep 'foo$' filename
Match line only containing foo:
grep '^foo$' filename
You can search for blank lines with the following examples:
grep '^$' filename
Zeichenklassen
Match Vivek or vivek:
grep '[vV]ivek' filename
OR
grep '[vV][iI][Vv][Ee][kK]' filename
You can also match digits (i.e match vivek1 or Vivek2 etc):
grep -w '[vV]ivek[0-9]' filename
You can match two numeric digits (i.e. match foo11, foo12 etc):
grep 'foo[0-9][0-9]' filename
You are not limited to digits, you can match at least one letter:
grep '[A-Za-z]' filename
Display all the lines containing either a "w" or "n" character:
grep [wn] filename
Within a bracket expression, the name of a character class enclosed in "[:" and ":]" stands for the list of all characters belonging to that class. Standard character class names are:* [:alnum:] - Alphanumeric characters.
- [:alpha:] - Alphabetic characters
- [:blank:] - Blank characters: space and tab.
- [:digit:] - Digits: '0 1 2 3 4 5 6 7 8 9'.
- [:lower:] - Lower-case letters: 'a b c d e f g h i j k l m n o p q r s t u v w x y z'.
- [:space:] - Space characters: tab, newline, vertical tab, form feed, carriage return, and space.
- [:upper:] - Upper-case letters: 'A B C D E F G H I J K L M N O P Q R S T U V W X Y Z'.
In this example match all upper case letters:
grep '[:upper:]' filename
Wildcards
You can use the "." for a single character match. In this example match all 3 character word starting with "b" and ending in "t":
grep '\<b.t\>' /etc/services
Where,* \< Match the empty string at the beginning of word
- \> Match the empty string at the end of word.
Print all lines with exactly two characters
grep '^..$' filename
Display any lines starting with a dot and digit
grep '^\.[0-9]' filename
Den Punkt maskieren
The following regex to find an IP address 192.168.1.254 will not work:
grep '192.168.1.254' /etc/hosts
All three dots need to be escaped:
grep '192\.168\.1\.254' /etc/hosts
The following example will only match an IP address:
egrep '[[:digit:]]{1,3}\.[[:digit:]]{1,3}\.[[:digit:]]{1,3}\.[[:digit:]]{1,3}' filename
The following will match word Linux or UNIX in any case:
egrep -i '^(linux|unix)' filename
Mustern mit führendem Bindestrich
Searches for all lines matching '--test--' using -e option Without -e, grep would attempt to parse '--test--' as a list of options:
grep -e '--test--' filename
Oder-Verknüpfung mit grep
Use the following syntax:
grep 'word1|word2' filename
OR
grep 'word1\|word2' filename
UND-Verknüpfung mit grep
Use the following syntax to display all lines that contain both 'word1' and 'word2'
grep 'word1' filenae | grep 'word2'
Sequenzen testen
You can test how often a character must be repeated in sequence using the following syntax:
{N} {N,} {min,max}
Match a character "v" two times:
egrep "v{2}" filename
The following will match both "col" and "cool":
egrep 'co{1,2}l' filename
The following will match any row of at least three letters 'c'.
egrep 'c{3,}' filename
The following example will match mobile number which is in the following format 91-1234567890 (i.e twodigit-tendigit)
grep "[[:digit:]]\{2\}[ -]\?[[:digit:]]\{10\}" filename
Treffer hervorheben
Use the following syntax:
grep --color regex filename
Nur Treffer, nicht Zeile anzeigen
Use the following syntax:
grep -o regex filename
Arbeiten mit grep
Einfache Wortsuche
$ grep root /etc/passwd
Zeigt alle Zeilen, die root in genau dieser Schreibweise enthalten.
Suche nach Wortvariationen
$ grep -i Root /etc/passwd
Ignoriert Groß-/Kleinschreibung.
$ grep will[iy] /etc/passwd
Findet Zeilen die willi und willy enthalten.
$ grep will[^y] /etc/passwd
Findet nicht willy nicht enthalten, aber willi, willo usw.
Leere Zeilen entfernen
$ grep -v '^$' /etc/services
Wenn ein Zeilenende $ auf einen Zeilenanfang ^ folgt so werden leere Zeilen gefunden. -v invertiert die Ergebnisse und gibt Leerzeilen nicht aus.
Kommentare filtern
grep -v '^#' /etc/services
Zeilen mit einem Kommentarzeichen # am Zeilenanfang ^ gelten in Shellskripten als Kommentare. -v invertiert die Ergebnisse und gibt Zeilen mit Kommentaren nicht aus.
Anzahl der Treffer ermitteln
$ grep -c '^#' /etc/services
Gibt die Anzahl der Kommentarzeilen in der Datei an.
Treffer im Zusammenhang sehen
$ grep -C2 NFS /etc/services
Zeigt Treffer mit den beiden Zeilen davor und danach.
In welcher Datei wird eine Variable gesetzt?
Bei der Systemadministration fragt man sich häufig, in welcher Datei eigentlich welche Shell-Variable gesetzt wird? Die globalen Vorgaben erfolgen zum Großteil in den Dateien des Verzeichnisses /etc.
Namen der Dateien, in denen z. B. die PATH-Variable modifiziert wird
grep -l PATH /etc/* 2>/dev/null /etc/csh.cshrc /etc/login.defs /etc/manpath.config /etc/profile /etc/profile.rpmsave /etc/rc.config /etc/squid.conf
Eventuell ist die Umleitung der Fehlerausgabe (2>/dev/null) sinnvoll.
Wie viele Benutzer sind Mitglied einer Gruppe?
Wie viele Nutzer sind Mitglied in der default-Gruppe users (GID 100)?
grep -c ':[0-9]\{1,\}:100:' /etc/passwd 9
Bei der Angabe des Suchmusters hilft uns die Kenntnis des Aufbaus der Datei »/etc/passwd«. * Dabei steht die GruppenID immer zwischen zwei Doppelpunkten.
- Allerdings könnte es sein, dass auch die NutzerID (UID) 100 vergeben ist - der Ausdruck :[0-9]\{1,\}:100: garantiert, dass :100: das zweite rein numerische Feld betrifft.
Eine andere Schreibweise wäre:
grep -c ':[[:digit:]]\{1,\}:100:' /etc/passwd 9
Netzwerkdienste über UDP
Welche Netzwerkdienste über UDP sind auf unserem System verfügbar (Datei /etc/inetd.conf)?
grep '^[^#].*[[:space:]]udp' /etc/inetd.conf time dgram udp wait root internal talk dgram udp wait root /usr/sbin/tcpd in.talkd ntalk dgram udp wait root /usr/sbin/tcpd in.talkd netbios-ns dgram udp wait root /usr/sbin/nmbd nmbd * Jede Zeile, die mit einem # beginnt, ist ein Kommentar.
- Also filtern wir solche Zeilen aus (^[^#]). Das gesuchte Protokoll ist "udp".
- Vor diesem Schlüsselwort können beliebig viele Zeichen (.*) gefolgt von einem Leerzeichen oder Tabulator ([[:space:]]) stehen.
Einfacher mit Pipe
Je gezielter man nach Informationen fahndet, desto verwirrender wird die Angabe der Suchmusters.
In zahlreichen Fällen wird die Verwendung von Pipes einleuchtender sein.
Das Ergebnis aus obigen Beispiel erhält man auch mit folgender Befehlsfolge:
grep -w udp /etc/inetd.conf | grep -v ^# time dgram udp wait root internal talk dgram udp wait root /usr/sbin/tcpd in.talkd ntalk dgram udp wait root /usr/sbin/tcpd in.talkd netbios-ns dgram udp wait root /usr/sbin/nmbd nmbd
Weitere Beispiele
In einer bestimmten Datei nach einem Wort suchen
grep suchwort datei.txt
Alle Dateien im aktuellen Ordner und Unterordnern, die einen bestimmten Text enthalten
grep -R "suchwort" *
Dateien im aktuellen Ordner, die wort1 oder wort2 im Inhalt haben
grep -E "(wort1|wort2)" *
Dateien in Unterordner
egrep -rni -e "ubuntuusers" /var/www * Findet rekursiv (-r) alle Dateien im Verzeichnis /var/www
- in denen die Zeichenkette ubuntuusers auftritt,
- unabhängig von Groß- und Kleinschreibung (Option -i).
- Die Treffer werden unter Angabe der Datei und der Zeilennummer (Option -n) auf der Standardausgabe ausgegeben.
Anzahl der Treffer
egrep -rc -e "toll" /usr/src * Gibt an, wie oft (Option -c) die Zeichenkette toll in welchen Dateien im Verzeichnis /usr/src vorkommt.
Fehler in Log-Datei
egrep -w "EE|WW" /var/log/Xorg.0.log * Durchsuchen einer speziellen Logdatei
- nach Zeilen, welche die Zeichenkette EE oder WW als Kennzeichnung von Fehlern und Warnungen enthalten,
- nicht jedoch nur vollständige Wörter wie SCREEN, welche ebenfalls EE enthalten.
Binärdateien nicht durchsuchen
grep -rIo "\-session" ~ * Durchsuchen des gesamten eigenen Homeverzeichnisses "~" mit nach Textdateien (Konfigurationsdateien, Logdateien, Textdokumente...),
- welche die Zeichenfolge -session (Option) enthalten.
- Binärdateien wie Videos werden durch -I ausgeschlossen,
- -o beschränkt die Zeichenkette auf das Suchwort -session.
- "\" verhindert eine Fehlermeldung von grep durch das fälschlicherweise Auswerten von
- -s aus -session als Option statt als Suchbegriff -session.
Suche nach den geladenen Soundtreibern
lsmod | grep snd
- Ausgabe aller geladenen Treiber, die als Module vorliegen, durch lsmod,
- wobei die Ausgabe durch den Operator "|" an grep umgeleitet wird.
- grep gibt nur die Zeilen aus, die die Zeichenfolge snd enthalten
Egrep - Beispiele
Egrep ist hilfreich, wenn Sie nach Zeilen in der Eingabe suchen, die mindestens eine von mehreren Zeichenketten enthalten.
So findet das folgende Beispiel alle Zeilen der Datei /etc/fstab, in denen »floppy« und »cdrom« auftauchen:
egrep 'floppy|cdrom' /etc/fstab /dev/hdc /cdrom iso9660 ro,noauto,user,exec 0 0 /dev/fd0 /floppy auto noauto,user 0 0
Eine weitere interessante Anwendung ist die Suche nach »geteilten« Mustern, d.h. die bekannten Teile stehen auf einer Zeile, aber der Zwischenraum ist unbekannt.
Zur Demonstration dient folgende Datei:
cat beispiel.txt 1 ein Zwischenraum 2 ein Zwischenraum 3 ein Zwischenraum 4 ein Zwischenraum
Gesucht werden sollen alle Zeilen, die »einen Zwischenraum« enthalten; jedoch ist die Zusammensetzung des Zwischenraums nicht bekannt (und besteht teils aus Leerzeichen, teils aus Tabulatoren und teils aus beidem).
Mit dem normalen grep könnte man sich mit folgendem Konstrukt behelfen:
grep "ein[[:space:]][[:space:]]*Zwischenraum" beispiel.txt 1 ein Zwischenraum 2 ein Zwischenraum 3 ein Zwischenraum 4 ein Zwischenraum
Die doppelte Anwendung des [:space:]-Musters ist für diesen Fall notwendiger Ballast, da wir ja mindestens einen Zwischenraum benötigen.
Eleganter ist da die Möglichkeit von "+" in Verbindung mit egrep:
egrep "ein[[:space:]]+Zwischenraum" beispiel.txt 1 ein Zwischenraum 2 ein Zwischenraum 3 ein Zwischenraum 4 ein Zwischenraum
Quellen
- man page grep and regex(7)
- info page grep
Links
- pgrep - gezielt nach der PID suchen / filternhttp://wiki.ubuntuusers.de/pgrep
- pdfgrep - PDF-Dateien durchsuchenhttp://wiki.ubuntuusers.de/pdfgrep
- grep in der Wikipediahttp://de.wikipedia.org/wiki/grep
- GNU grephttp://www.gnu.org/software/grep/
- Erklärung regulärer Ausdrückehttp://de.wikipedia.org/wiki/Regulärer_Ausdruck
Grafische Werkzeuge
Für den Einsatz innerhalb einer Desktop-Umgebung sind gedacht: * Searchmonkeyhttp://searchmonkey.embeddediq.com/