[[Vorlage(getestet, general)]] {{{#!vorlage Wissen [:Terminal: Ein Terminal öffnen] }}} [[Inhaltsverzeichnis(2)]] [[Bild(Wiki/Icons/terminal.png, 48, align=left)]] Mit '''grep''' lassen sich Dateien nach bestimmten Textstücken durchsuchen. Die Suchmuster werden "regular expressions" (auf Deutsch: [#Links regulärer Ausdruck]) genannt. Sie sind vielfältig einsetzbar, und werden nicht nur von grep verwendet. = Reguläre Ausdrücke = Bevor es an die Beschreibung des Befehls geht, soll noch kurz erläutert werden, wie man das, was man sucht, überhaupt beschreibt. Die Beschreibung eines Textmusters wird als ''regular expression (regulärer Ausdruck)'' bezeichnet. Sie sind ähnlich mathematischen Ausdrücken aufgebaut: kleinere Untereinheiten werden durch Operatoren miteinander verknüpft. `grep` verwendet drei Variationen von regular expressions: ''basic'', ''extended'' und ''PCRE'' (Perl-compatible regular expressions). Die folgenden Beschreibungen beziehen sich auf die ''extended'' Variante. Um diese beim Aufruf von ``grep`` zu verwenden, kann es entweder mit dem Parameter ``-E`` aufgerufen werden, oder durch den alternativen Befehl ``egrep``. Die grundlegenden Einheiten eines regulären Ausdrucks sind solche, die ein einzelnes Zeichen beschreiben. Die meisten Zeichen (darunter alle Buchstaben und Ziffern) passen auf sich selbst, zum Beispiel passt "``4``" auf alle Vieren in einer Zeichenkette, also z.B. '''4'''56, PMA'''4'''Life, Hausnummer'''4''' usw... . Alle Zeichen mit einer besonderen Bedeutung (wie zum Beispiel der Punkt "``.``") lassen sich durch das Voranstellen eines Rückstrichs "\" ihrer besonderen Bedeutung berauben. Um also einen Punkt "." zu finden muss man in dem regulären Ausdruck ein "``\.``" verwenden. Um den Rückstrich selbst zu finden, benötigt man ein "``\\``". == 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 ''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 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: {{{#!vorlage befehl 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: * `[:digit:]` alle Ziffern, also `[0-9]` * `[:upper:]` alle Großbuchstaben * `[:lower:]` alle Kleinbuchstaben * `[:alpha:]` alle Buchstaben, also `[[:upper:][:lower:]]` * `[:alnum:]` alle Ziffern oder Buchstaben, also `[[:digit:][:alpha:]]` * `[:punct:]` alle Satzzeichen bzw. Sonderzeichen * `[:graph:]` alle graphischen Zeichen, also `[[:alnum:][:punct:]]` * `[:print:]` druckbare Zeichen, also `[ [:graph:]]` * `[:blank:]` Leerzeichen oder Tabulator * `[:space:]` Zeichen die Leerraum erzeugen (Leerzeichen, Tabulator, Zeilenvorschub etc.) * `[:cntrl:]` alle Steuerzeichen Die vordefinierten Listen müssen aber auch in eckige Klammern eingeschlossen zu werden: {{{ # falsch: grep -E '[:alnum:]' Datei # findet z.B. 'a', da es eines der Zeichen ':alnum:' ist, aber nicht 'b' oder '1' (die vordefinierte Liste wird nicht als solche interpretiert!) # richtig: grep -E '[mark][[/mark][:alnum:][mark]][/mark]' Datei # findet sowohl 'a', als auch 'b' oder '1', da die vordefinierte Liste nun als "Buchstabe oder Zahl" interpretiert wird # auch richtig: grep -E '[mark][[/mark][:alnum:] [mark]][/mark]' Datei # findet zusätzlich zu Buchstaben und Zahlen auch Leerzeichen # auch richtig: grep -E '[0-9a-zA-Z]' Datei # entspricht [[:alnum:]] }}} == 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. * "``{,m}``" Der vorangegangene Ausdruck ist optional und wird maximal m-mal angetroffen. * "``{n,m}``" Der vorangegangene Ausdruck wird mindestens 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. = Installation = Das Programm '''grep''' ist im essentiellen Paket * '''grep''' von Ubuntu enthalten und ist deshalb auf jedem System installiert. = Aufruf von grep = {{{#!vorlage Befehl grep [Optionen] Muster [Datei...] }}} oder {{{#!vorlage Befehl 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`` sowie ||Basis/Variante || bz || lz || xz || z || zip || ||grep || bzgrep || lzgrep || xzgrep || zgrep || zipgrep || || ||egrep || bzegrep || lzegrep || xzegrep || zegrep || || ||fgrep || bzfgrep || lzfgrep || xzfgrep || zfgrep || || für das Suchen in komprimierten Dateien, ohne diese explizit auspacken zu müssen für die Kompressionsformate bz, lz, xz, z und zip und * grep-aptavail * grep-available * grep-dctrl * grep-debtags * grep-status Diese sind spezialisierte ''grep'' aufbauende Programme, um Debian-Paketverwaltungsdateien zu durchsuchen. * pgrep sucht in der aktuellen Prozessliste * ptargrep greppt im Inhalt von Dateien in Tar-Dateien. = Beschreibung = Mit ``grep`` lassen sich Zeichenketten in Dateien finden, die auf die angegebenen ''regular expressions'' passen. Wird keine Datei angegeben, so wird die Standardeingabe verwendet. == 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`` || 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. Die Vorgabe 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 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. || || `` -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. || = Beispiele = {{{#!vorlage Befehl 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. {{{#!vorlage Befehl egrep -rc -e "toll" /usr/src }}} Gibt an, wie oft (Option `-c`) die Zeichenkette `toll` in welchen Dateien im Verzeichnis '''/usr/src''' vorkommt. {{{#!vorlage Befehl egrep -w "EE|WW" /var/log/Xorg.0.log }}} Durchsuchen einer speziellen [:Logdateien:Logdatei] nach Zeilen, welche die Zeichenkette `EE` oder `WW` als Kennzeichnung von Fehlern und Warnungen enthalten, nicht jedoch als Bestandteil von Wörtern wie `SCREEN`. Der jeweilige Treffer bildet vielmehr ein eigenständiges (durch Leerzeichen oder Satzzeichen getrenntes) "Wort". {{{#!vorlage Befehl grep -vf foo bar }}} Gibt alle Zeilen der Datei "bar" aus, in welchen keines der in der Datei "foo" gelisteten Muster enthalten ist. {{{#!vorlage Befehl sudo grep -rIo "\-session" ~ }}} Durchsuchen des gesamten eigenen [:Homeverzeichnis:Homeverzeichnisses] "`~`" mit [:sudo:]-Rechten nach Textdateien ([:Software_Problembehebung#Saubere-Konfiguration: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`. {{{#!vorlage Befehl lsmod | grep snd }}} Ausgabe aller geladenen Treiber, die als Module vorliegen, durch `lsmod`, wobei die Ausgabe durch den [:/Shell/Bash-Skripting-Guide_für_Anfänger#Umleitungen:Operator] "`|`" an `grep` umgeleitet wird. `grep` gibt nur die Zeilen aus, die die Zeichenfolge `snd` enthalten (Suche nach den geladenen Soundtreibern). {{{#!vorlage Befehl if grep -q "foo" bar; then echo "Die Datei bar enthält den Begriff foo."; fi }}} Wenn der Begriff "foo" in der Datei "bar" gefunden wird, wird eine entsprechende Meldung auf den Bildschirm ausgegeben. = Grafische Werkzeuge = Für den Einsatz innerhalb einer Desktop-Umgebung sind gedacht: * [https://searchmonkey.sourceforge.net/ searchmonkey] {en} - in den offiziellen Paketquellen enthalten * [http://regexxer.sourceforge.net/ regexxer] {en} - in den offiziellen Paketquellen enthalten * [sourceforge:jgrep:jGrep] {en} - auf [:Java:] basierend * [https://sethoscope.net/grepui/ grepui] {en} = Links = * [https://manpages.ubuntu.com/manpages/bionic/de/man1/grep.1.html manpage] {de} * [https://www.regular-expressions.info/ Regular-Expressions.info] {en} – Webseite mit vielen Informationen zu regulären Ausdrücken * [:tre-agrep:] - Werkzeug zur "unscharfen" Suche mit regulären Ausdrücken * [:pgrep:] - gezielt nach der PID suchen / filtern * [:pdfgrep:] - PDF-Dateien durchsuchen * [:gron:] - JSON-Daten leichter mit grep durchsuchen * [:YARA:] - kann Text- und Binärdateien durchsuchen * [wikipedia:grep:grep bei Wikipedia] * [http://www.gnu.org/software/grep/ GNU grep] {en} * [wikipedia:Regulärer_Ausdruck#Regul.C3.A4re_Ausdr.C3.BCcke_in_der_Praxis:Erklärung regulärer Ausdrücke] * [https://medium.com/@rualthanzauva/grep-was-a-private-command-of-mine-for-quite-a-while-before-i-made-it-public-ken-thompson-a40e24a5ef48 Blogeintrag] {en} zur Historie von grep * [https://www.youtube.com/watch?v=NTfOnGZUZDk Computerphile: Brian Kernighan, Where GREP Came From] Namensherkunft in Video (10 min., {en}) erklärt # tag: Shell