grep
-Familie
"Global search for a regular expression and print out matched lines" - kurz grep
ist das gebräuchlichste
Kommando, um in Dateien nach bestimmten Mustern zu suchen. Die grep
-Familie umfasst die drei Kommandos egrep
,
grep
und fgrep
. Das erste "Extended grep" (erweitertes grep) versteht "ein paar mehr" der Regulären Ausdrücke
als grep
. fgrep
hingegen unterstützt nur eine eingeschränkte Teilmenge, womit sich die Suche vor allem in
großen Dateien erheblich beschleunigen lässt.
grep
arbeitet bei der Suche wesentlich effizienter als das in einem Editor geschehen wrde. Per Voreinstellung schreibt das
Kommando alle Zeilen der Eingabe, die das gesuchte Muster enthalten, auf die Standardausgabe. Dabei kann die Eingabe beliebig viele
Dateien, als auch die Standardeingabe betreffen. Zudem liefern die Kommandos der
grep
-Familie einen Rückgabewert an das Betriebssystem, was sie für die Verwendung in Shellprogrammen
bevorzugt.
grep
Rückgabewert | Bedeutung |
0 | Muster wurde gefunden |
1 | Muster wurde nicht gefunden |
2 | Datei nicht gefunden |
# "root" sollte es eigentlich in jeder "passwd" geben
|
grep
Option | Wirkung und Beispiel | |
-c |
Anzeige der Anzahl Zeilen, in denen das Muster gefunden wurde:
|
|
-i |
Groß- und Kleinschreibung werden nicht unterschieden:
|
|
-l |
Nur Anzeige der Namen der Dateien, in denen das Muster gefunden wurde:
|
|
-n |
Zeigt die Zeilennummer an, in der das Muster gefunden wurde:
|
|
-s |
Unterdrückt die Fehlerausgaben (Standardfehler); sinnvoll in Skripten. | |
-v |
Zeigt alle Zeilen an, die das Muster nicht enthalten:
|
|
-w |
Das Suchmuster muss ein einzelnes Wort sein (also kein Bestandteil eines anderen Wortes). | |
-A [n] |
Zeigt
|
|
-B [n] |
Zeigt Anzahl Zeilen an, die vor der Zeile mit dem Muster liegen. |
grep
unterstützte Reguläre Ausdrücke
In nachfolgender Tabelle sind alle Reguläre Ausdrücke aufgeführt, die die Kommandos der grep
-Familie
unterstützen. Ein "g" in der Spalte "?grep" besagt, dass dieser Ausdruck vom "normalen" grep
unterstützt wird;
ein "e" betrifft egrep
. fgrep
arbeitet wie grep
, außer, dass alle Sonderzeichen ihre
Wirkung verlieren.
Reg.Ausdruck | ?grep | Wirkung |
^ |
ge | Beginn der Zeile |
$ |
ge | Ende der Zeile |
. |
ge | Genau ein beliebiges Zeichen |
* |
ge | Beliebig viele des vorangegangenen Zeichens |
[] |
ge | 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:]. |
[^] |
ge | Kein Zeichen aus dem Bereich |
\< |
g | Muster am Wortanfang suchen |
\> |
g | Muster am Wortende suchen |
\(..)\ |
g | Eingeschlossenes Muster vormerken; auf dieses kann später über \1 zugegriffen werden. Bis zu neun
Muster können auf diese Weise gespeichert werden (Beispiel). |
x\{m\} |
g | m -faches Auftreten des Zeichens x |
x\{m,n\} |
g | mindestens m -, maximal n -maliges Auftreten des Zeichens x |
+ |
e | Mindestens ein Auftreten des vorangegangenen Zeichens |
? |
e | Höchstens ein Auftreten des vorangegangenen Zeichens |
x|y |
e | Zeichen "x" oder Zeichen "y" |
(abc|xyz) |
e | Zeichenkette "abc" oder Zeichenkette "xyz" |
Einfache Beispiele zur Anwendung von grep
begegneten uns schon an mehreren Stellen
dieses Buches. Nun möchte ich versuchen, anhand typischer Anforderungen bei der alltäglichen
Arbeit mit einem Unix-System, die Verwendung der komplexeren Mechanismen zu erläutern.
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
. Also
interessieren uns die Namen der Dateien, in denen z.B. die PATH
-Variable modifiziert wird:
user@sonne> grep -l PATH /etc/* 2>/dev/null
|
Die Umleitung der Fehlerausgabe nach /dev/null
ist sinnvoll, da grep
nicht auf
Verzeichnisse anwendbar ist.
Wieviele Nutzer sind Mitglied in der default-Gruppe users
(GID 100)?
user@sonne> grep -c ':[0-9]\{1,\}:100:' /etc/passwd
|
Bei der Angabe des Suchmusters hilft uns die Kenntnis des Aufbaus der
user@sonne> grep -c ':[[:digit:]]\{1,\}:100:' /etc/passwd
9
Welche Netzwerkdienste über UDP sind auf unserem System verfügbar (siehe Datei /etc/inetd.conf)?
user@sonne> grep '^[^#].*[[:space:]]udp' /etc/inetd.conf
|
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 beliebige viele
beliebige Zeichen (.*
) gefolgt von einem Leerzeichen oder
Tabulator ([[:space:]]
)stehen.
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:
user@sonne> grep -w udp /etc/inetd.conf | grep -v ^#
|