»Global search for a regular expression and print out matched lines« - kurz 'g/re/p'1) ist das gebräuchlichste Kommando, um in Dateien nach bestimmten Mustern zu suchen. Das grep-Kommando kann aus einer oder mehreren Dateien lesen oder wenn keine Datei angegeben wird von der Standardeingabe gelesen. Per Default schreibt das grep-Kommando alle Zeilen der Eingabe, die das gesuchte Muster enthalten, auf die Standardausgabe.
Die Syntax des grep-Kommandos lautet:
$ grep [options] PATTERN [FILE…] $ grep [options] [-e PATTERN | -f FILE] [FILE…]
Optionen:
Option | Beschreibung |
---|---|
-r | Setze die Suche rekursiv durch alle Unterverzeichnisse fort. Funktioniert nur bei der Verwendung von Wildcards einwandfrei |
-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 »n« Zeilen an, die der Zeile mit dem Muster folgen |
-B [n] | Zeigt »n« Zeilen an, die vor der Zeile mit dem Muster liegen |
--color=auto | Hebt das gesuchte Muster farblich hervor |
Beispiele:
Da für jeden User in der Datei /etc/passwd eine eigene Zeile verwendet wird, zeigt die Option '-c' die Anzahl der Benutzer, die im System die Loginshell /bin/false haben:
$ grep -c /bin/false /etc/passwd 38
Zeige die Zeilen der /etc/passwd die das Suchmuster 'root' enthalten und ignoriere Gross- und Kleinschreibung des Suchmusters:
$ grep -i RooT /etc/passwd root:x:0:0:root:/root:/bin/bash
Zeige alle Dateien die das Suchmuster tcp enthalten und hebe die gefundenen Suchmuster farbig hervor:
$ grep --color=auto -I tcp /etc/hosts.* /etc/hosts.allow:# See 'man tcpd' and 'man 5 hosts_access' for a detailed description /etc/hosts.allow:# tcp_wrappers support: /etc/hosts.allow:# by inetd or xinetd use tcpd to "wrap" the network connection. tcpd uses /etc/hosts.allow:# mail -s "tcp_wrappers on %H" root
Suche in allen Dateien im derzeitigen Verzeichnis und rekursiv in allen Unterverzeichnissen (-r) nach dem String datadir und zeige den gesuchten String
in der Ausgabe farbig an:
$ grep -r --color=auto datadir * bin/wantedpages.php: $trunclen = strlen($conf['datadir'].':'); bin/wantedpages.php:$START_DIR = $conf['datadir']; bin/indexer.php: search($data,$conf['datadir'],'search_allpages',array());
Unterdrücke Fehlermeldungen bei der Ausgabe:
$ grep -s root /var/log/*
/var/log/system.log:Apr 6 09:04:33 localhost kernel[0]: Darwin Kernel Version 9.8.0: Wed Jul 15 16:55:01 PDT 2009; root:xnu-1228.15.4~1/RELEASE_I386
/var/log/system.log:Apr 6 09:04:33 localhost kernel[0]: rooting via boot-uuid from /chosen: 7ED1B186-4FF6-318E-A20C-F81803F2D063
/var/log/system.log:Apr 6 09:04:33 localhost kernel[0]: BSD root: disk0s2, major 14, minor 2
Der selbe Befehl ohne Unterdrückung der Fehlermeldungen:
$ grep root /var/log/* grep: /var/log/krb5kdc: Permission denied ← Diese Fehlermeldung wird durch die Option -s unterdrückt grep: /var/log/secure.log: Permission denied ← Diese Fehlermeldung wird durch die Option -s unterdrückt /var/log/system.log:Apr 6 09:04:33 localhost kernel[0]: Darwin Kernel Version 9.8.0: Wed Jul 15 16:55:01 PDT 2009; root:xnu-1228.15.4~1/RELEASE_I386 /var/log/system.log:Apr 6 09:04:33 localhost kernel[0]: rooting via boot-uuid from /chosen: 7ED1B186-4FF6-318E-A20C-F81803F2D063 /var/log/system.log:Apr 6 09:04:33 localhost kernel[0]: BSD root: disk0s2, major 14, minor 2
Zeige alle Zeilen in der Datei /etc/vsftpd.conf in der das Suchmuster 'local' nur als solches vorkommt und nicht ein Bestandteil eines Wortes ist (Ignoriere zB localhost):
$ grep -w local /etc/vsftpd.conf
# Uncomment this to allow local users to log in.
# Default umask for local users is 077. You may wish to change this to 022,
Suche in der Datei /var/log/vsftpd.log nach dem Muster "USER ftpuser", ignoriere dabei Gross- und Kleinschreibung (-i) und zeige auch die dem Suchmuster folgenden drei Zeilen an (-A 3):
$ grep -i -A 3 "User ftpuser" /var/log/vsftpd.log Tue Apr 6 13:49:57 2010 [pid 8121] FTP command: Client "192.168.1.1", "USER ftpuser" Tue Apr 6 13:49:57 2010 [pid 8121] [ftpuser] FTP response: Client "192.168.1.1", "331 Please specify the password." Tue Apr 6 13:49:57 2010 [pid 8121] [ftpuser] FTP command: Client "192.168.1.1", "PASS <password>" Tue Apr 6 13:49:58 2010 [pid 8118] [ftpuser] OK LOGIN: Client "192.168.1.1"
Man kann die Ausgabe eines Befehls auch mittels einer Pipe dem grep-Befehl übergeben (Standardeingabe). Im folgenden Beispiel zeigt ps -eaf die gesamte Prozessliste an, die Ausgabe wird mit einer Pipe (|) an den grep-Befehl weitergereicht, welcher die Prozessliste nach dem Suchmuster vsftpd filtert:
$ ps -eaf | grep vsftpd nobody 7358 2735 0 10:48 ? 00:00:00 vsftpd: 88.67.12.123: connected ftpuser 7362 7358 0 10:48 ? 00:00:01 vsftpd: 88.67.12.123/ftpuser: IDLE root 8085 7950 0 13:39 pts/0 00:00:00 grep vsftpd
Filtere aus dem vorangegangenen Befehl die Ausgabe des grep-Befehls aus:
$ ps -eaf | grep vsftpd | grep -v grep nobody 7358 2735 0 10:48 ? 00:00:00 vsftpd: 88.67.12.123: connected misc 7362 7358 0 10:48 ? 00:00:01 vsftpd: 88.67.12.123/ftpuser: IDLE
Reguläre Ausdrücke
Die Suchmuster lassen ist mit regulären Ausdrücken sehr fein einstellen. Werden mehrere reguläre Ausdrücke hintereinander verwendet, müssen diese mit einem »|«-Zeichen getrennt werden. Bei der Eingabe von Sonderzeichen wie zB »?, +, {, |, (, und )« müssen diese durch einen Backslash vor der Interpretation durch die Shell geschützt werden. Man kann jedoch an Stelle von grep das egrep-Kommando verwenden. »grep« und »egrep« interpretieren reguläre Ausdrücke unterschiedlich. Für »grep« haben runde Klammern und der senkrechte Strich zum Beispiel keine besondere Bedeutung. Sollen sie zur Bildung von regulären Ausdrücken verwendet werden, muß ihnen ein Backslash vorangstellt werden. Anders bei »egrep«. Hier haben sie automatisch ihre besondere Bedeutung. Wie das jeweilige Programm diese Sonderzeichen behandelt, ist im einzelnen in der Manpage nachzulesen.
regex | Beschreibung | Beispiel | |
---|---|---|---|
^ | Beschreibt den Beginn einer Zeile | ^[a-e]: Zeile beginnt mit den Buchstaben a bis e | |
$ | Beschreibt das Ende einer Zeile | \.$: Zeile endet mit einem Punkt | |
\< | Beschreibt den Wortanfang | \<hal: Wort beginnt mit hal | |
\> | Beschreibt das Wortende | ung\>: Wort endet mit ung | |
\b | Steht am Wortanfang oder Wortende | s\b: Wort beginnt entweder oder endet mit einem s | |
{n,m} | Suchmuster kommt mindestens n-mal und maximal m-mal vor | a\{1,2\}: Der Buchstabe a kommt mindestens einmal und maximal zweimal vor |
Beispiele:
Einer meiner Dozenten ging früher mit uns mal eine Wette ein, dass jeder der mehr als vier deutsche Substantive findet, die mit 'nf' enden, von ihm zum Mittagessen eingeladen wird. Eigentlich ging es bei der Aufgabe darum diese mit awk zu lösen aber grep eignet sich dazu genau so gut. Als erstes brauchen wir mal eine Textdatei mit allen Wörtern die im Deutschen vorkommen. Ich habe dazu die Datei Deutsch.dic auf meinem Desktop liegen:
$ grep -i 'nf\>' ~/Desktop/Deutsch.dic fünf genf hanf senf
Der folgende Ausdruck sucht im Wörterbuch nach sämtlichen Varianten des Namens Meier zB: Mayr; Meier etc. Dabei bedeutet ^M dass das Suchmuster mit 'M' beginnt, wobei durch den Schalter -i die Gross- und Kleinschreibung ignoriert wird; als nächster Buchstabe entweder ein 'a' oder ein 'e' erwartet wird [ae]; der darauf folgende Buchstabe entweder ein 'i' oder ein 'y' ist [iy]; danach ein 'e' kommen kann (aber nicht muss) e\{0,1\} und das Wort mit einem 'r' endet r\>:
$ grep -i '^M[ae][iy]e\{0,1\}r\>' ~/Desktop/Deutsch.dic maier mayer meier meyer mair mayr
— pronto 2010/04/06 23:16