4.3 grep
Kommen wir nun zu einem weiteren Programm namens grep. grep kann ähnlich wie sed Filterausdrücke aus einem Inputstream filtern. Jedoch kann grep diese nicht manipulieren. Vielmehr liegen die Stärken von grep in der einfachen Handhabung und in der höheren Geschwindigkeit gegenüber sed.
Zum Filtern von Ausdrücken übergibt man grep einfach den gewünschten Ausdruck und entweder eine Eingabedatei oder den Input aus einer Pipe bzw. manuell über die Standardeingabe.
$ grep 'n$' Standorte
Bremen
Friedrichshafen
Aschersleben
Berlin
Essen
Furtwangen
Kehlen
Kempten
Listing 4.18 grep
Filternegierung
Zudem kann man die Filtervorgabe negieren, womit grep alle Zeilen ausgibt, die nicht dem angegebenen Ausdruck entsprechen. Dies wird mit der -v-Option bewerkstelligt.
$ grep -v 'n$' Standorte
Augsburg
Bernburg
Halle
Krumbach
Osnabrueck
Listing 4.19 grep -v
4.3.1 grep -E und egrep
Sehr hilfreich ist die Fähigkeit, mehrere Ausdrücke in einem Befehl zu filtern. Dabei verwendet man ein logisches »ODER« in Form eines Pipe-Zeichens zwischen den Ausdrücken und entweder grep mit der Option -E oder das Programm egrep.
$ egrep -v 'n$|k$' Standorte Augsburg Bernburg Halle Krumbach $ grep -vE 'n$|k$' Standorte Augsburg Bernburg Halle Krumbach
Listing 4.20 egrep
Ein Blick in die Manpage verrät uns das Geheimnis: egrep ist mit einem Aufruf von grep –E gleichzusetzen. Zudem findet man im Dateisystem, zumindest unter Slackware-Linux, den symbolischen Link /bin/egrep auf /bin/grep. Dies bedeutet, dass das Programm grep intern abfragt, ob der Programmname »egrep« oder nur »grep« ist, und sein Verhalten der Option -E im Falle von »egrep« automatisch anpasst.
4.3.2 Geschwindigkeitsvergleich
Da wir einen Test auf einen regulären Ausdruck sowohl mit sed als auch mit grep durchführen können, interessiert uns natürlich, welches Programm das schnellere ist. Besonders Shellskripts, die große String-Mengen durchsehen müssen, können dadurch eventuell sinnvoll optimiert werden.
Zum Test erzeugen wir eine 188 MB große Datei mit dem Namen »TESTFILEB«, in der unterschiedlich lange Textstrings enthalten sind. Das Testsystem läuft unter Slackware-Linux 9.1 mit Kernel-2.4.22, einem AMD Athlon XP 2400+-Prozessor und einer UDMA133-Platte. Hier nun die Testaufrufe sowie deren Ergebnisse:
- sed -n '/n$/p' TESTFILEB >/dev/null
- benötigte im Schnitt 9,358 Sekunden, um diese Datenmenge zu bewältigen.
- grep 'n$' TESTFILEB >/dev/null
- benötigte durchschnittlich nur 7,075 Sekunden.
- Ein von uns speziell für diesen einen Filtervorgang entwickeltes, geschwindigkeitsoptimiertes, vom GNU-Compiler gcc-3.2.3 optimiertes, gestriptes C-Programm, in dem die darin verwendeten Standard-Libc-Funktionen strlen() und bzero() durch schnellere ersetzt wurden, benötigte übrigens nur noch 5.940 Sekunden. <Man könnte den Test noch schneller absolvieren, indem man beispielsweise auf Assembler zurückgreift, die Testdatei in eine virtuelle Partition im Hauptspeicher auslagert (oder komplett in den RAM einliest), eventuell eine andere Kernel-Version verwendet oder schlicht auf bessere Hardware zurückgreift.>