GNU/Linux >> LINUX-Kenntnisse >  >> Linux

Reguläre Ausdrücke:Alles zusammenziehen

In Einführung in reguläre Ausdrücke , habe ich das Konzept und die Grundlagen vorgestellt und dann in Erste Schritte mit regulären Ausdrücken:Ein Beispiel , sind wir ein Beispiel durchgegangen, das Listen mit Namen und E-Mail-Adressen bereinigt, damit sie konsistent und parsbar sind. Nach unserem Einstieg in Regex und grep:Datenfluss und Bausteine , wo wir näher auf reguläre Ausdrücke eingegangen sind, ist es nun an der Zeit, Möglichkeiten zu erkunden, wie wir das Befehlszeilenprogramm aus dem ersten Beispiel verkürzen und vereinfachen können. Wir konzentrieren uns hier auf grep und sed .

Beispiel:Vereinfachung des Mailinglisten-Programms

Lassen Sie uns zunächst auf unser erstes Beispiel zurückblicken, in dem wir das folgende Befehlszeilenschnittstellenprogramm (CLI) erstellt haben:

cat Experiment_6-1.txt | grep -v Team | grep -v "^\s*$" | sed -e "s/[Ll]eader//" -e "s/\[//g" -e "s/]//g" -e "s/)//g" -e "s/(//g" | awk '{print $1" "$2" <"$3">"}'

Vielleicht finden Sie die regulären Ausdrücke an dieser Stelle leichter lesbar, aber dieses Programm kann vereinfacht werden.

cat und grep

Beginnen wir damit, uns auf den Anfang des Befehls zu konzentrieren, der cat beinhaltet und grep :

cat Experiment_6-1.txt | grep -v Team | grep -v "^\s*$"

Wir können die beiden grep kombinieren Anweisungen, die ursprünglich so aussehen:

| grep -v Team | grep -v "^\s*$" 

Tipp: Wenn das STDOUT von grep wird nicht durch ein anderes Dienstprogramm geleitet, und wenn Sie einen Terminalemulator verwenden, der Farbe unterstützt, werden die Regex-Übereinstimmungen im Ausgabedatenstrom hervorgehoben.

Der überarbeitete Befehl lautet:

grep -vE "Team|^\s*$"

Hier haben wir das E hinzugefügt Option, die erweiterte Regex angibt. Gemäß dem grep Manpage:

"In GNU grep gibt es keinen Unterschied in der verfügbaren Funktionalität zwischen grundlegender und erweiterter Syntax."

Diese Aussage ist nicht ganz richtig, da unser neuer kombinierter Ausdruck ohne das E fehlschlägt Möglichkeit. Führen Sie Folgendes aus, um die Ergebnisse anzuzeigen:

[student@studentvm1 testing]$ cat Experiment_6-1.txt | grep -vE "Team|^\s*$"

Versuchen Sie es ohne das E Option.

Sehen wir uns nun cat an . Das grep Das Tool kann auch Daten aus einer Datei lesen, sodass wir die cat eliminieren können Befehl vollständig:

[student@studentvm1 testing]$ grep -vE "Team|^\s*$" Experiment_6-1.txt

Diese Änderung und die vorherige zusammen ergeben das folgende, etwas vereinfachte CLI-Programm:

grep -vE "Team|^\s*$" Experiment_6-1.txt | sed -e "s/[Ll]eader//" -e "s/\[//g" -e "s/]//g" -e "s/)//g" -e "s/(//g" | awk '{print $1" "$2" <"$3">"}'

Dieser Befehl ist kürzer, prägnanter und wird schneller ausgeführt, weil grep muss den Datenstrom nur einmal parsen.

Hinweis: Auch hier ist es wichtig zu erkennen, dass diese Lösung nicht die einzige ist. Es gibt verschiedene Methoden in Bash, um dieselbe Ausgabe zu erzeugen, und es gibt andere Sprachen wie Python und Perl, die ebenfalls verwendet werden können. Und natürlich gibt es immer LibreOffice Writer-Makros. Aber ich kann mich immer auf Bash als Teil jeder Linux-Distribution verlassen. Ich kann diese Aufgaben mit Bash-Programmen auf jedem Linux-Computer ausführen, sogar auf einem ohne GUI-Desktop oder auf einem mit einem GUI-Desktop, auf dem LibreOffice jedoch nicht installiert ist.

gesendet

Wir können auch den sed vereinfachen Befehl. Der sed Das Dienstprogramm ermöglicht nicht nur die Suche nach Text, der mit einem Regex-Muster übereinstimmt, es kann auch den übereinstimmenden Text ändern, löschen oder ersetzen. Ich verwende sed in der Befehlszeile und in Bash-Shell-Skripten als schnelle und einfache Möglichkeit, Text zu finden und zu ändern. Der Name sed steht für Stream-Editor, da es Datenströme auf die gleiche Weise verarbeitet wie andere Tools, die einen Datenstrom umwandeln können. Die meisten dieser Änderungen bestehen darin, bestimmte Zeilen aus dem Datenstrom auszuwählen und sie an ein anderes Transformationsprogramm weiterzugeben.

Hinweis: Viele Leute nennen Tools wie grep Programme filtern , weil sie unerwünschte Zeilen aus dem Datenstrom herausfiltern. Ich bevorzuge den Begriff Transformatoren , weil Tools wie sed und awk mehr als nur filtern. Sie können den Inhalt für verschiedene Zeichenfolgenkombinationen testen und den übereinstimmenden Inhalt auf viele verschiedene Arten ändern. Tools wie sort , head , tail , uniq , fmt , und mehr wandeln den Datenstrom auf irgendeine Weise um.

sed haben wir bereits gesehen in Aktion, aber jetzt, mit einem Verständnis für reguläre Ausdrücke, können wir unsere frühere Verwendung besser analysieren und verstehen. Es ist möglich, vier der fünf in sed verwendeten Ausdrücke zu kombinieren Befehl in einen einzigen Ausdruck. Der sed Befehl hat jetzt zwei statt fünf Ausdrücke:

sed -e "s/[Ll]eader//" -e "s/[]()\[]//g"

Dieses Format macht es etwas schwierig, den komplexeren Ausdruck zu verstehen. Beachten Sie, dass unabhängig von der Anzahl der Ausdrücke ein einzelner sed Befehl enthält, wird der Datenstrom nur einmal geparst, um alle Ausdrücke abzugleichen.

Untersuchen wir den überarbeiteten Ausdruck genauer:

-e "s/[]()\[]//g"

Standardmäßig sed interpretiert alle [ Zeichen als Anfang eines Satzes und das letzte ] Zeichen als Ende dieses Satzes. Also, im obigen Code, der erste [ und der letzte ] den Satz enthalten. Der dazwischenliegende ] Zeichen werden nicht als Metazeichen interpretiert.

Da wir [ als Literalzeichen, um es aus dem Datenstrom zu entfernen, und sed interpretiert normalerweise [ als Metazeichen müssen wir es maskieren, damit es als wörtlicher ] interpretiert wird . Dort wird der Backslash (\ ) kommt herein und gibt uns \[ in der Mitte.

Lassen Sie uns diese neue Version in das CLI-Skript einbinden und testen:

[student@studentvm1 testing]$ grep -vE "Team|^\s*$" Experiment_6-1.txt | sed -e "s/[Ll]eader//" -e "s/[]()\[]//g"

Ich weiß, was Sie fragen:"Warum nicht den \[ nach dem [ das den Satz öffnet, und vor dem ] Zeichen?" Versuchen Sie es wie ich:

[student@studentvm1 testing]$  grep -vE "Team|^\s*$" Experiment_6-1.txt | sed -e "s/[Ll]eader//" -e "s/[\[]()]//g"`

Ich denke, das sollte funktionieren, tut es aber nicht. Kleine unerwartete Ergebnisse wie dieses machen deutlich, dass wir vorsichtig sein und jede Regex sorgfältig testen müssen, um sicherzustellen, dass sie tatsächlich das tut, was wir beabsichtigen.

Nach einigen eigenen Experimenten entdeckte ich, dass die linke eckige Klammer \[ funktioniert gut in allen Positionen des Ausdrucks außer der ersten. Dieses Verhalten wird im grep vermerkt Manpage, die ich wahrscheinlich zuerst hätte lesen sollen. Ich finde jedoch, dass das Experimentieren die Dinge, die ich lese, verstärkt, und ich entdecke normalerweise interessantere Dinge als das, wonach ich gesucht habe.

Hinzufügen der letzten Komponente, des awk Statement, unser optimiertes Programm sieht so aus und die Ergebnisse sind genau das, was wir wollen:

[student@studentvm1 testing]$ grep -vE "Team|^\s*$" Experiment_6-1.txt | sed -e "s/[Ll]eader//" -e "s/[]()\[]//g" | awk '{print $1" "$2" <"$3">"}'

Andere Tools, die reguläre Ausdrücke implementieren

Viele Linux-Tools implementieren reguläre Ausdrücke. Die meisten dieser Implementierungen sind denen von awk sehr ähnlich , grep , und sed , daher sollte es einfach sein, die Unterschiede zu erkennen. Obwohl wir uns awk nicht im Detail angesehen haben, ist es eine mächtige Textverarbeitungssprache, die auch reguläre Ausdrücke implementiert.

Die meisten fortgeschritteneren Texteditoren verwenden reguläre Ausdrücke. Vim, gVim, Kate und GNU Emacs sind keine Ausnahmen. Das less Dienstprogramm implementiert reguläre Ausdrücke, ebenso wie die Such- und Ersetzungsfunktion von LibreOffice Writer.

Programmiersprachen wie Perl, awk und Python enthalten auch Implementierungen von regulären Ausdrücken, wodurch sie sich gut für Schreibwerkzeuge zur Textbearbeitung eignen.

Ressourcen

Ich habe einige hervorragende Ressourcen gefunden, um etwas über reguläre Ausdrücke zu lernen. Es gibt mehr, als ich hier aufgelistet habe, aber diese habe ich als besonders nützlich empfunden:

  • Das grep man-Seite hat eine gute Referenz, ist aber nicht geeignet, um etwas über reguläre Ausdrücke zu lernen.
  • Das Buch von O’Reilly, Mastering Regular Expressions , von Jeffrey E. F. Friedl, ist eine gute Anleitung und Referenz für reguläre Ausdrücke. Ich empfehle es jedem, der ein Linux-Systemadministrator ist oder werden möchte, da Sie reguläre Ausdrücke verwenden werden.
  • Das O’Reilly-Buch sed &awk:UNIX Power Tools , von Arnold Robbins und Dale Dougherty, ist ein weiterer guter. Es behandelt diese beiden leistungsstarken Tools und enthält auch eine ausgezeichnete Diskussion über reguläre Ausdrücke.

Es gibt auch einige gute Websites, die Ihnen helfen können, etwas über reguläre Ausdrücke zu lernen, und die interessante und nützliche Regex-Beispiele im Kochbuchstil bieten. Es gibt einige, die Geld verlangen, um sie zu benutzen. Jason Baker, mein technischer Gutachter für die Bände 1 und 2 meines Buches Using and Administering Linux Natürlich schlägt regexcrossword.com als gutes Lernwerkzeug vor.

Zusammenfassung

Diese Serie hat eine kurze Einführung in die komplexe Welt der regulären Ausdrücke gegeben. Wir haben die Regex-Implementierung in grep untersucht Dienstprogramm in gerade genug Tiefe, um Ihnen eine Vorstellung von einigen der erstaunlichen Dinge zu geben, die mit Regexes erreicht werden können. Wir haben uns auch mehrere Linux-Tools und Programmiersprachen angesehen, die ebenfalls reguläre Ausdrücke implementieren.

Aber machen Sie keinen Fehler! Wir haben nur an der Oberfläche dieser Werkzeuge und der regulären Ausdrücke gekratzt. Es gibt noch viel mehr zu lernen, und wie Sie sehen, gibt es einige hervorragende Ressourcen dafür.

Hinweis: Dieser Artikel ist eine leicht modifizierte Version von Kapitel 6 aus Band 2 meines Linux-Selbstlernkurses „Using and Administering Linux:Zero to SysAdmin“, der Ende 2019 bei Apress erscheinen soll.


Linux
  1. Auflisten aller E-Mail-Adressen in einer Datei mit grep

  2. Bash:Reguläre Ausdrücke als Ersatz?

  3. Wird \d von den grundlegenden Ausdrücken von grep nicht unterstützt?

  4. Warum funktioniert `\d` nicht in regulären Ausdrücken in sed?

  5. Wie grep ich eine Zeichenfolge in einem Verzeichnis und allen seinen Unterverzeichnissen?

Erste Schritte mit regulären Ausdrücken

Reguläre Ausdrücke in Grep (Regex)

Wie man nach mehreren Zeichenfolgen und Mustern grep

So führen Sie eine Grep-Suche für alle Dateien und in allen Verzeichnissen durch

10 praktische Beispiele für Regex mit grep

grep Extraktnummernbereich