Advanced Bash Regex mit Beispielen

Advanced Bash Regex mit Beispielen

Mit der Kraft regulärer Ausdrücke kann man textbasierte Dokumente und Zeichenfolgen analysieren und transformieren. Dieser Artikel ist für fortgeschrittene Benutzer gedacht, die bereits mit grundlegenden regulären Ausdrücken in Bash vertraut sind. Eine Einführung in die regulären Ausdrücke finden. Ein weiterer Artikel, den Sie vielleicht interessant finden, sind reguläre Ausdrücke in Python.

Bereit anzufangen? Tauchen Sie ein und lernen Sie, Regexps wie einen Profi zu verwenden!

In diesem Tutorial lernen Sie:

  • So vermeiden Sie kleine Unterschiede im Betriebssystem, weil sie Ihre regulären Ausdrücke beeinflussen können
  • Wie man vermeidet, um zu generischen regulären Ausdrucksuche zu verwenden, wie .*
  • Wie man regelmäßige Expressionsyntax einsetzt oder nicht, oder nicht, um sie zu verwenden oder nicht zu verwenden
  • Beispiele für komplexe reguläre Ausdrücke in Bash erweiterte Verwendung
Advanced Bash Regex mit Beispielen

Softwareanforderungen und Konventionen verwendet

Softwareanforderungen und Linux -Befehlszeilenkonventionen
Kategorie Anforderungen, Konventionen oder Softwareversion verwendet
System Linux-Verteilungsunabhängige
Software BASH -Befehlszeile, Linux -basiertes System
Andere Die SED -Nützlichkeit wird als Beispielwerkzeug zum Einsatz regelmäßiger Ausdrücke verwendet
Konventionen # - Erfordert, dass gegebene Linux -Commands mit Root -Berechtigungen entweder direkt als Stammbenutzer oder mithilfe von verwendet werden können sudo Befehl
US

Beispiel 1: Heads Up, um erweiterte reguläre Ausdrücke zu verwenden

Für dieses Tutorial werden wir SED als unsere Hauptausdrucks -Verarbeitungsmotor verwenden. Alle angegebenen Beispiele können normalerweise direkt auf andere Motoren portiert werden, z.

Eine Sache, die Sie bei der Arbeit mit regulären Ausdrücken immer berücksichtigen sollten, ist, dass einige Regex -Motoren (wie die in SED) sowohl regelmäßige als auch erweiterte reguläre Expressionsyntax unterstützen. Zum Beispiel ermöglicht SED Sie die Verwendung der Verwendung -E Option (Abkürzungsoption für --regexp-erweitert) und ermöglicht es Ihnen, erweiterte reguläre Ausdrücke im SED -Skript zu verwenden.

Praktisch führt dies zu kleinen Unterschieden in den regulären Expressionssyntax -Idiomen beim Schreiben regulärer Expressionskripte. Schauen wir uns ein Beispiel an:

$ echo 'sample' | sed 's | [a-e] \+| _ | g' s_mpl_ $ echo 'sample' | sed 's | [a-e]+| _ | g' sample $ echo 'sample+' | sed 's | [a-e]+| _ | g' sample_ $ echo 'sample' | sed -e 's | [a -e]+| _ | g' s_mpl_ 


Wie Sie sehen können, haben wir in unserem ersten Beispiel verwendet \+ Um den A-C-Bereich zu qualifizieren (weltweit ersetzt durch die G Qualifikationsmittel) als erforderlich ein oder mehrere Ereignisse. Beachten Sie, dass die Syntax speziell ist \+. Als wir dies jedoch geändert haben \+ Zu +, Der Befehl ergab eine völlig andere Ausgabe. Das liegt daran, dass die + wird nicht als Standard -Plus -Zeichen und nicht als Regex -Befehl interpretiert.

Dies wurde anschließend durch den dritten Befehl beweist, in dem ein wörtlicher Teil +, ebenso wie e vorher wurde vom regulären Ausdruck erfasst [a-e]+, und verwandelt sich in _.

Wenn wir den ersten Befehl zurückblicken, können wir jetzt sehen, wie die \+ wurde als nicht-literaler regulärer Ausdruck interpretiert +, von SED bearbeitet werden.

Schließlich sagen wir im letzten Befehl SED, dass wir die erweiterte Syntax mit dem verwenden möchten -E erweiterte Syntaxoption zu SED. Beachten Sie, dass der Begriff erweitert gibt uns einen Hinweis darauf, was im Hintergrund passiert; Die reguläre Ausdrucksyntax ist erweitert So aktivieren Sie verschiedene Regex -Befehle, wie in diesem Fall +.

Einmal der -E wird verwendet, obwohl wir noch verwenden + und nicht \+, Sed interpretiert die richtig + Als reguläre Ausdrucksanweisung.

Wenn Sie viele reguläre Ausdrücke schreiben, verblassen diese geringfügigen Unterschiede bei der Ausdruck Ihrer Gedanken in regelmäßige Ausdrücke in den Hintergrund, und Sie werden sich tendenziell an die wichtigsten erinnern.

Dies unterstreicht auch die Notwendigkeit, regelmäßige Ausdrücke immer ausgiebig zu testen, da eine Vielzahl möglicher Eingaben auch solche, die Sie nicht erwarten.

Beispiel 2: Änderung der Hochleistungs -String -Änderung

In diesem und den nachfolgenden Beispielen haben wir eine Textdatei vorbereitet. Wenn Sie miteinander üben möchten, können Sie die folgenden Befehle verwenden, um diese Datei für sich selbst zu erstellen:

$ echo 'abcdefghijklmnopqrstuvwxyz abcdefg 0123456789'> Test1 $ Cat Test1 Abcdefghijklmnopqrstuvwxyz Abcdefg 0123456789 

Schauen wir uns nun unser erstes Beispiel für String -Modifikationen an: Wir möchten die zweite Spalte (ABCDEFG) vor dem ersten zu kommen (ABCDEFGHIJKLMNOPQRSTUVWXYZ).

Als Anfang machen wir diesen fiktiven Versuch:

$ cat test1 AbcdefghijklMnopqrstuvwxyz abcdefg 0123456789 $ cat Test1 | sed -e | ([a -o]+).*([A-z]+) | \ 2 \ 1 | ' G ABCDEFGHIJKLMNO 0123456789 

Verstehst du diesen regulären Ausdruck?? In diesem Fall sind Sie bereits ein sehr fortgeschrittener regelmäßiger Ausdrucksschreiber, und Sie können sich entscheiden, zu den folgenden Beispielen zu springen, um sie zu überfliegen, um festzustellen, ob Sie sie schnell verstehen können oder ein bisschen Hilfe benötigen.

Was wir hier tun, ist zu Katze (Anzeige) Unsere Test1 -Datei und analysieren Sie sie mit einem erweiterten regulären Ausdruck (dank der -E Option) mit SED. Wir hätten diesen regulären Ausdruck unter Verwendung eines nicht erweiterten regulären Ausdrucks (in SED) wie folgt schreiben können;

$ cat test1 | sed 's | \ ([a-o] \+\).*\ ([A-z] \+\) | \ 2 \ 1 | ' G ABCDEFGHIJKLMNO 0123456789 

Das ist genau das gleiche, außer dass wir a hinzugefügt haben \ Charakter vor jedem (, ) Und + Charakter, der auf SED hinweist. Wir möchten, dass sie als regulärer Ausdruckscode analysiert werden, und nicht als normale Zeichen. Schauen wir uns jetzt den regulären Ausdruck selbst an.

Lassen Sie uns das erweiterte reguläre Ausdrucksformat dafür verwenden, da es leichter visuell analysieren kann.

S | ([a-o]+).*([A-z]+) | \ 2 \ 1 | 

Hier verwenden wir den SED -Ersatzbefehl (S zu Beginn des Befehls), gefolgt von einer Suche (zuerst |… | Teil) und ersetzen (zweite |… | Teil) Abschnitt.

Im Suchabschnitt haben wir zwei Auswahlgruppen, jedes umgeben und begrenzt von durch ( Und ), nämlich ([a-o]+) Und ([A-z]+). Diese Auswahlgruppen werden in ihrer Reihenfolge beim Durchsuchen der Saiten gesucht. Beachten Sie, dass wir zwischen der Auswahlgruppe a haben .* Regelmäßiger Ausdruck, was im Grunde genommen bedeutet Jeder Charakter, 0 oder mehrmals. Dies passt zu unserem Raum dazwischen ABCDEFGHIJKLMNOPQRSTUVWXYZ Und ABCDEFG in der Eingabedatei und möglicherweise mehr.

In unserer ersten Suchgruppe suchen wir mindestens ein Ereignis von a-o gefolgt von einer anderen Anzahl von Vorkommen von a-o, angezeigt durch die + Qualifikation. In der zweiten Suchgruppe suchen wir nach Großbuchstaben dazwischen A Und Z, und dies wieder ein oder mehrmals nacheinander.

Schließlich in unserem Ersatzabschnitt der Ersatz sed Befehl regelmäßiger Ausdruck, wir werden Rufen Sie zurück/erinnern Sie sich Der von diesen Suchgruppen ausgewählte Text und fügen Sie sie als Ersatzketten ein. Beachten Sie, dass die Reihenfolge umgekehrt wird; Ausgabe zuerst den Text, der mit der zweiten Auswahlgruppe übereinstimmt (durch die Verwendung von \ 2 Angabe der zweiten Auswahlgruppe), dann der Text übereinstimmt mit der ersten Auswahlgruppe (\ 1).

Während dies einfach klingen mag, das Ergebnis an der Hand (G ABCDEFGHIJKLMNO 0123456789) kann nicht sofort klar sein. Wie haben wir uns verloren? ABCDEF Zum Beispiel? Wir haben auch verloren pqrstuvwxyz - Hast du bemerkt?



Was passiert ist, ist das; Unsere erste Auswahlgruppe erfasste den Text ABCDEFGHIJKLMNO. Dann gegeben die .* (Jeder Charakter, 0 oder mehrmals) Alle Charaktere wurden abgestimmt - und dies wichtig; So maximal Grad - bis wir den nächsten zutreffenden passenden regulären Ausdruck finden, falls vorhanden,. Dann haben wir schließlich jeden Brief aus dem abgestimmt A-z Bereich und dies noch einmal.

Fangen Sie an zu verstehen, warum wir verloren haben ABCDEF Und pqrstuvwxyz? Während es keineswegs selbstverständlich ist, die .* passend zu den Charakteren bis zur zuletzt A-z wurde abgestimmt, was sein würde G im ABCDEFG Saite.

Obwohl wir angegeben haben ein oder mehr (Durch den Gebrauch von +) Die zu übereinstimmenden Zeichen, dieser spezielle reguläre Ausdruck wurde von SED von links nach rechts korrekt interpretiert, und SED hielt nur mit dem passenden Charakter an (montiert (.*) wenn es nicht mehr die Prämisse erfüllen konnte, dass es es geben würde mindestens ein Großbuchstaben A-z Charakter bevorstehend.

In Summe, PQRSTUVWXYZ ABCDEF wurde durch .* anstelle des Raums, wie man diesen regulären Ausdruck in einem natürlicheren, aber falschen Lesen lesen würde. Und weil wir nicht fangen, was von dem ausgewählt wurde, von dem wir ausgewählt wurden .*, Diese Auswahl wurde einfach aus der Ausgabe fallen gelassen.

Beachten Sie auch, dass alle nicht vom Suchabschnitt übereinstimmenden Teile einfach in die Ausgabe kopiert werden: sed wird nur auf alles reagieren, was der reguläre Ausdruck (oder die Textübereinstimmung) findet.

Beispiel 3: Auswählen alles, was nicht ist

Das vorherige Beispiel führt uns auch zu einer anderen interessanten Methode, die Sie wahrscheinlich ein gutes Stück verwenden werden, wenn Sie regelmäßig reguläre Ausdrücke schreiben, und das besteht Alles was nicht ist. Klingt nach einer lustigen Sache zu sagen, aber nicht klar, was es bedeutet? Schauen wir uns ein Beispiel an:

$ cat test1 AbcdefghijklMnopqrstuvwxyz abcdefg 0123456789 $ cat Test1 | sed -e 's | [^]*| _ |' _ ABCDEFG 0123456789 

Ein einfacher regulärer Ausdruck, aber ein sehr mächtiger. Hier anstatt zu verwenden .* In irgendeiner Form oder Art und Weise haben wir verwendet [^]*. Anstatt zu sagen (von .*) Passen Sie einen beliebigen Charakter an, 0 oder mehrmals, Wir geben jetzt an Passen Sie einen beliebigen Nicht-Raum-Charakter an, 0 oder mehrmals.

Während dies relativ einfach aussieht, werden Sie bald die Kraft des Schreibens regulärer Ausdrücke auf diese Weise erkennen. Denken Sie zum Beispiel über unser letztes Beispiel zurück, in dem wir plötzlich einen großen Teil des Textes auf etwas unerwartete Weise übereinstimmen. Dies könnte vermieden werden, indem unser regulärer Ausdruck aus dem vorherigen Beispiel leicht geändert wird:

$ cat test1 | sed -e 's | ([a-o]+) [^a]+([a-z]+) | \ 2 \ 1 |' ABCDEFG ABCDEFGHIJKLMNO 0123456789 

Noch nicht perfekt, aber schon besser; Zumindest konnten wir bewahren ABCDEF Teil. Wir haben nur verändert .* Zu [^A]+. Mit anderen Worten, suchen Sie weiter nach Charakteren, mit Ausnahme von mindestens einen A. Einmal A Es wird festgestellt, dass ein Teil des regulären Ausdrucks an Parsen stoppt. A selbst wird auch nicht in das Spiel aufgenommen.

Beispiel 4: Zurück zu unserer ursprünglichen Anforderung zurückkehren

Können wir es besser machen und tatsächlich die ersten und zweiten Spalten korrekt tauschen??

Ja, aber nicht, indem Sie den regulären Ausdruck wie-is behalten. Schließlich tut es das, was wir darum gebeten haben; übereinstimmen alle Zeichen von a-o Verwenden der ersten Suchgruppe (und später am Ende der Zeichenfolge ausgeben) und dann verwerfen Jeder Charakter, bis SED erreicht A. Wir konnten eine endgültige Lösung des Problems durchführen - denken Sie daran, wir wollten, dass nur der Raum übereinstimmt - indem wir das erweitern/ändern a-o Zu a-z, oder indem Sie einfach eine andere Suchgruppe hinzufügen und den Raum buchstäblich abgleichen:

$ cat test1 | sed -e 's | ([a-o]+) ([^]+) [] ([a-z]+) | \ 3 \ 1 \ 2 |' ABCDEFG ABCDEFGHIJKLMNOPQRSTUVWXYZ 0123456789 

Großartig! Aber der reguläre Ausdruck sieht jetzt zu komplex aus. Wir haben zusammengestellt a-o ein oder mehrmals in der ersten Gruppe, dann jeder Nicht-Raum A-z ein oder mehrmals.

Können wir es vereinfachen?? Ja. Und dies sollte hervorheben, wie man regelmäßige Expressionskripte leicht überkomplizieren kann.

$ cat test1 | sed -e 's | ([^]+) ([^]+) | \ 2 \ 1 |' ABCDEFG ABCDEFGHIJKLMNOPQRSTUVWXYZ 0123456789 $ CAT Test1 | awk 'print $ 2 "" $ 1 "" $ 3' abcdefg abcdefghijklmnopqrstuvwxyz 0123456789 


Beide Lösungen erreichen die ursprüngliche Anforderung, verwenden verschiedene Tools, einen stark vereinfachten Regex für den SED -Befehl und ohne Fehler, zumindest für die bereitgestellten Eingangszeichenfolge. Kann das leicht schief gehen?

$ cat test1 AbcdefghijklMnopqrstuvwxyz abcdefg 0123456789 $ cat Test1 | sed -e 's | ([^]+) ([^]+) | \ 2 \ 1 |' ABCDEFGHIJKLMNOPQRSTUVWXYZ 0123456789 ABCDEFG 

Ja. Wir haben nur einen zusätzlichen Speicherplatz in die Eingabe hinzugefügt, und die Verwendung desselben regulären Ausdrucks ist jetzt völlig falsch. Die zweite und dritte Säulen wurden anstelle der Faust zwei getauscht. Auch hier wird die Notwendigkeit, reguläre Ausdrücke ausführlich und mit unterschiedlichen Eingängen zu testen, hervorgehoben. Der Ausgangsunterschied liegt einfach daran.

Beispiel 5: ls gotcha?

Manchmal eine Einstellung zur Betriebssystemebene, wie beispielsweise die Verwendung von Farbausgaben für Verzeichnislisten oder nicht (die standardmäßig standardmäßig festgelegt werden kann!), veranlasst Befehlszeilenskripte, sich unregelmäßig zu verhalten. Obwohl es auf jeden Fall ein direkter Fehler der regulären Ausdrücke ist, ist es ein Gotcha, auf den man bei der Verwendung regulärer Ausdrücke leichter begegnen kann. Schauen wir uns ein Beispiel an:

LS Color Output hob das Ergebnis eines Befehls mit regelmäßigen Ausdrücken
$ ls -d t* test1 test2 $ ls -d t* 2 | sed 's | 2 | 1 |' test1 $ ls -d t*2 | sed 's | 2 | 1 |' | xargs ls ls: Kann nicht zugreifen "

In diesem Beispiel haben wir ein Verzeichnis (test2) und eine Datei (test1), die beide vom Original aufgeführt werden ls -d Befehl. Dann suchen wir nach allen Dateien mit einem Dateinamenmuster von t*2, und entfernen Sie die 2 vom Dateinamen mit sed. Das Ergebnis ist der Text prüfen. Es sieht so aus, als ob wir diese Ausgabe verwenden können prüfen Sofort für einen anderen Befehl, und wir haben es über gesendet Xargs zum ls Befehl erwarten die ls Befehl zur Auflistung der Datei Test1.

Dies geschieht jedoch nicht, und stattdessen erhalten wir eine sehr komplexe Ausgabe von Parse-Parse zurück. Der Grund ist einfach: Das ursprüngliche Verzeichnis wurde in einer dunkelblauen Farbe aufgeführt, und diese Farbe ist definiert als eine Reihe von Farbcodes. Wenn Sie dies zum ersten Mal sehen, ist die Ausgabe schwer zu verstehen. Die Lösung ist jedoch einfach;

$ ls -d -color = nie t*2 | sed 's | 2 | 1 |' | xargs ls test1 

Wir haben das gemacht ls Befehl Ausgabe der Auflistung ohne Verwendung einer Farbe. Dies behebt das Problem vollständig und zeigt uns, wie wir uns im Hinterkopf behalten können verschiedene Hardware oder auf verschiedenen Betriebssystemen.

Bereit, selbst weiter zu erkunden? Schauen wir uns einige der häufigsten regulären Ausdrücke an, die in Bash verfügbar sind:

Ausdruck Beschreibung
. Jeder Charakter außer Newline
[A-C] Ein Zeichen des ausgewählten Bereichs, in diesem Fall a, b, c
[A-Z] Ein Zeichen des ausgewählten Bereichs, in diesem Fall A-Z
[0-9AF-Z] Ein Zeichen des ausgewählten Bereichs in diesem Fall 0-9, A und F-Z
[^A-za-z] Ein Charakter außerhalb des ausgewählten Bereichs, in diesem Fall beispielsweise '1', würde sich qualifizieren
\* oder * Eine beliebige Anzahl von Übereinstimmungen (0 oder mehr). Verwenden Sie * bei Verwendung regulärer Ausdrücke, bei denen erweiterte Ausdrücke nicht aktiviert sind (siehe das erste Beispiel oben)
\+ oder + 1 oder mehr Übereinstimmungen. IDEM -Kommentar als *
\ (\) Erfassungsgruppe. Wenn dies zum ersten Mal verwendet wird, ist die Gruppennummer 1 usw.
^ Beginn der String
$ Ende der String
\D Eine Ziffer
\D Ein nicht digitaler
\S Ein weißer Raum
\S Ein nichtweißer Raum
a | d Ein Zeichen aus beiden (eine Alternative zur Verwendung []), 'a' oder 'D'
\ Es entkommt Sonderzeichen oder gibt an, dass wir einen regulären Ausdruck verwenden möchten, bei dem erweiterte Ausdrücke nicht aktiviert sind (siehe das erste Beispiel oben)
\B Rückenraumcharakter
\N Newline -Charakter
\R Wagenrücklaufcharakter
\T Tab -Zeichen

Abschluss

In diesem Tutorial haben wir uns bei Bash regelmäßigen Ausdrücken ausführlich angesehen. Wir haben die Notwendigkeit entdeckt, unsere regulären Ausdrücke ausführlich mit unterschiedlichen Eingängen zu testen. Wir haben auch gesehen, wie kleine Betriebssystemunterschiede, wie die Verwendung von Farbe für ls Befehle oder nicht können zu sehr unerwarteten Ergebnissen führen. Wir haben gelernt, dass wir die Notwendigkeit vermeiden müssen, zu generische reguläre Expressions-Such-Muster zu vermeiden und die Verwendung erweiterter regulärer Ausdrücke zu verwenden.

Schreiben Sie gerne fortgeschrittene reguläre Ausdrücke und hinterlassen Sie uns unten einen Kommentar mit Ihren coolsten Beispielen!

Verwandte Linux -Tutorials:

  • Bash Regexps für Anfänger mit Beispielen
  • Python reguläre Ausdrücke mit Beispielen
  • Big Data Manipulation zum Spaß und Gewinn Teil 3
  • Eine Einführung in Linux -Automatisierung, Tools und Techniken
  • Dinge zu installieren auf Ubuntu 20.04
  • Big Data Manipulation zum Spaß und Gewinn Teil 2
  • Big Data Manipulation zum Spaß und Gewinn Teil 1
  • Mastering -Bash -Skriptschleifen beherrschen
  • Mint 20: Besser als Ubuntu und Microsoft Windows?
  • Dinge zu tun nach der Installation Ubuntu 20.04 fokale Fossa Linux