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

Erste Schritte mit regulären Ausdrücken:Ein Beispiel

In Einführung in reguläre Ausdrücke , habe ich behandelt, was sie sind und warum sie nützlich sind. Jetzt brauchen wir ein reales Beispiel, das wir als Lernwerkzeug verwenden können. Hier ist einer, dem ich vor einigen Jahren begegnet bin.

Dieses Beispiel unterstreicht die Leistungsfähigkeit und Flexibilität der Linux-Befehlszeile, insbesondere der regulären Ausdrücke, für ihre Fähigkeit, allgemeine Aufgaben zu automatisieren. Ich habe während meiner Karriere mehrere Listservs administriert und tue es immer noch. Die Leute schicken mir E-Mail-Adressen, um sie zu diesen Listen hinzuzufügen. In mehr als einem Fall habe ich eine Liste mit Namen und E-Mail-Adressen im Microsoft Word-Format erhalten, die einer der Listen hinzugefügt werden soll.

Die Problemliste

Die Liste selbst war nicht sehr lang, aber in ihrer Formatierung uneinheitlich. Eine gekürzte Version dieser Liste mit Namens- und Domänenänderungen wird hier angezeigt:

Team 1	Apr 3 
Leader  Virginia Jones  [email protected]	
Frank Brown  [email protected]	
Cindy Williams  [email protected]	
Marge smith   [email protected] 
 [Fred Mack]   [email protected]	

Team 2	March 14
leader  Alice Wonder  [email protected]	
John broth  [email protected]	
Ray Clarkson  [email protected]	
Kim West    [email protected]	
[JoAnne Blank]  [email protected]	

Team 3	Apr 1 
Leader  Steve Jones  [email protected]	
Bullwinkle Moose [email protected]	
Rocket Squirrel [email protected]	
Julie Lisbon  [email protected]	
[Mary Lastware) [email protected]

Die ursprüngliche Liste hatte zusätzliche Zeilen, Zeichen wie Klammern und Klammern, die gelöscht werden müssen, Leerzeichen wie Leerzeichen und Tabulatoren und einige leere Zeilen. Das erforderliche Format zum Hinzufügen dieser E-Mails zur Liste ist <first> <last> <[email protected]> . Unsere Aufgabe ist es, diese Liste in ein Format umzuwandeln, das von der Mailinglisten-Software verwendet werden kann.

Es war offensichtlich, dass ich die Daten manipulieren musste, um sie in ein akzeptables Format für die Eingabe in die Liste zu bringen. Es ist möglich, einen Texteditor oder ein Textverarbeitungsprogramm wie LibreOffice Writer zu verwenden, um die notwendigen Änderungen an dieser kleinen Datei vorzunehmen. Allerdings schicken mir Leute ziemlich oft Dateien wie diese, so dass es zu einer lästigen Pflicht wird, ein Textverarbeitungsprogramm zu verwenden, um diese Änderungen vorzunehmen. Trotz der Tatsache, dass Writer eine gute Such- und Ersetzungsfunktion hat, muss jedes Zeichen oder jede Zeichenfolge einzeln ersetzt werden, und es gibt keine Möglichkeit, frühere Suchen zu speichern.

Writer hat eine leistungsstarke Makrofunktion, aber ich bin mit keiner der beiden Sprachen vertraut:LibreOffice Basic oder Python. Ich kenne die Bash-Shell-Programmierung.

Ich habe getan, was für einen Systemadministrator selbstverständlich ist – ich habe die Aufgabe automatisiert. Als Erstes kopierte ich die Adressdaten in eine Textdatei, damit ich sie mit Befehlszeilentools bearbeiten konnte. Nach ein paar Minuten Arbeit habe ich das im vorherigen Artikel gezeigte Bash-Befehlszeilenprogramm entwickelt:

$ 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" | awk '{print $1" "$2" <"$3">"}' > addresses.txt

Dieser Code erzeugte die gewünschte Ausgabe als Datei addresses.txt . Ich habe meinen normalen Ansatz zum Schreiben von Befehlszeilenprogrammen wie diesem verwendet, indem ich die Pipeline Befehl für Befehl aufgebaut habe.

Lassen Sie uns diese Pipeline in ihre Bestandteile zerlegen, um zu sehen, wie sie funktioniert und zusammenpasst. Alle Experimente in dieser Reihe sollten als nicht privilegierter Benutzer durchgeführt werden. Ich habe dies auch auf einer VM gemacht, die ich zum Testen erstellt habe:studentvm1 .

Die Beispieldatei

Zuerst müssen wir die Beispieldatei erstellen. Erstellen Sie ein Verzeichnis namens testing auf Ihrem lokalen Computer und kopieren Sie dann den folgenden Text in eine neue Textdatei mit dem Namen Experiment_6-1.txt , das die drei oben gezeigten Teameinträge enthält.

Team 1  Apr 3 
Leader  Virginia Jones  [email protected]
Frank Brown  [email protected]
Cindy Williams  [email protected]
Marge smith   [email protected] 
 [Fred Mack]   [email protected]  

Team 2  March 14
leader  Alice Wonder  [email protected]
John broth  [email protected]  
Ray Clarkson  [email protected]
Kim West    [email protected] 
[JoAnne Blank]  [email protected]

Team 3  Apr 1 
Leader  Steve Jones  [email protected]
Bullwinkle Moose [email protected]
Rocket Squirrel [email protected]  
Julie Lisbon  [email protected]

Unnötige Zeilen mit grep entfernen

Die ersten Dinge, die ich sehe, die getan werden können, sind ein paar einfache. Da sich die Teamnamen und -daten in eigenen Zeilen befinden, können wir die folgenden Zeilen verwenden, um die Zeilen zu entfernen, die das Wort "Team:" enthalten

[student@studentvm1 testing]$  cat Experiment_6-1.txt | grep -v Team

Ich werde die Ergebnisse der einzelnen Phasen des Erstellens dieses Bash-Programms nicht reproduzieren, aber Sie sollten in der Lage sein, die Änderungen im Datenstrom zu sehen, wie sie auf STDOUT, der Terminalsitzung, angezeigt werden. Wir werden es bis zum Ende nicht in einer Datei speichern.

In diesem ersten Schritt, um den Datenstrom in einen verwendbaren umzuwandeln, verwenden wir den grep Befehl mit einem einfachen wörtlichen Muster, Team . Literale sind die einfachste Art von Mustern, die wir als reguläre Ausdrücke verwenden können, da es im durchsuchten Datenstrom nur eine einzige mögliche Übereinstimmung gibt, und das ist die Zeichenfolge Team .

Wir müssen leere Zeilen verwerfen, damit wir ein anderes grep verwenden können Erklärung, um sie zu beseitigen. Ich finde das, indem ich den regulären Ausdruck für den zweiten grep einschließe Der Befehl in Anführungszeichen stellt sicher, dass er richtig interpretiert wird:

[student@studentvm1 testing]$ cat Experiment_6-1.txt | grep -v Team | grep -v "^\s*$"
Leader  Virginia Jones  [email protected]
Frank Brown  [email protected]
Cindy Williams  [email protected]
Marge smith   [email protected] 
 [Fred Mack]   [email protected]  
leader  Alice Wonder  [email protected]
John broth  [email protected]  
Ray Clarkson  [email protected]
Kim West    [email protected] 
[JoAnne Blank]  [email protected]
Leader  Steve Jones  [email protected]
Bullwinkle Moose [email protected]
Rocket Squirrel [email protected]  
Julie Lisbon  [email protected]
[Mary Lastware) [email protected]
[student@studentvm1 testing]$

Der Ausdruck "^\s*$" veranschaulicht Anker und verwendet den umgekehrten Schrägstrich (\) als Escape-Zeichen um die Bedeutung eines wörtlichen "s" (in diesem Fall) in ein Metazeichen zu ändern, das alle Leerzeichen wie Leerzeichen, Tabulatoren oder andere nicht druckbare Zeichen bedeutet. Wir können diese Zeichen in der Datei nicht sehen, aber sie enthält einige davon.

Das Sternchen, auch Splat (*) genannt, gibt an, dass wir mit null oder mehr Leerzeichen übereinstimmen müssen. Dieser Zusatz würde mehrere Tabulatoren, mehrere Leerzeichen oder eine beliebige Kombination davon in einer ansonsten leeren Zeile finden.

Zusätzliche Leerzeichen mit Vim anzeigen

Als nächstes habe ich meinen Vim-Editor so konfiguriert, dass er Leerzeichen mit sichtbaren Zeichen anzeigt. Tun Sie dies, indem Sie Ihrer eigenen ~.vimrc die folgende Zeile hinzufügen Datei oder in die globale /etc/vimrc Konfigurationsdatei:

set listchars=eol:$,nbsp:_,tab:<->,trail:~,extends:>,space:+

Dann starten – oder neu starten – Vim.

Ich habe bei meinen Recherchen, wie man das macht, viele schlechte, unvollständige und widersprüchliche Informationen im Internet gefunden. Die integrierte Vim-Hilfe enthält die besten Informationen, und die Datenzeile, die ich oben erstellt habe, funktioniert für mich.

Hinweis: Im folgenden Beispiel werden normale Leerzeichen als + dargestellt; Registerkarten werden als < angezeigt , <> , oder <–> , und füllen Sie die Länge des Raums aus, den die Registerkarte abdeckt. Das Zeilenendezeichen (EOL) wird als $ angezeigt .

Das Ergebnis vor jeder Operation an der Datei wird hier angezeigt:

Team+1<>Apr+3~$
[email protected]<-->$
[email protected]<---->$
[email protected]<--->$
[email protected]~$
+[Fred+Mack][email protected]<>$
$
Team+2<>March+14$
[email protected]<----->$
[email protected]<>$
[email protected]<-->$
[email protected]>$
[JoAnne+Blank][email protected]<---->$
$
Team+3<>Apr+1~$
[email protected]<-->$
[email protected]<--->$
[email protected]<>$
[email protected]<------>$
[Mary+Lastware)[email protected]$

Unnötige Zeichen mit sed entfernen

Sie können sehen, dass viele Leerzeichen aus unserer Datei entfernt werden müssen. Wir müssen auch das Wort „Leader“ loswerden, das zweimal vorkommt und einmal großgeschrieben wird. Lassen Sie uns zuerst "Leader" loswerden. Dieses Mal verwenden wir sed (Stream-Editor), um diese Aufgabe auszuführen, indem er eine neue Zeichenfolge – oder in unserem Fall eine Null-Zeichenfolge – für das übereinstimmende Muster ersetzt.

Hinzufügen von sed -e "s/[Ll]eader//" zur Pipeline macht dies:

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

In diesem sed Befehl, -e bedeutet, dass der in Anführungszeichen eingeschlossene Ausdruck ein Skript ist, das ein gewünschtes Ergebnis erzeugt. Im Ausdruck die s bedeutet, dass es sich um eine Substitution handelt. Die Grundform einer Substitution ist s/<regex>/<replacement string>/ , also /[Ll]eader/ ist unser Suchstring.

Der Satz [Ll] stimmt mit L überein oder l , also [Ll]eader stimmt mit leader überein oder leader . In diesem Fall ist die Ersetzungszeichenfolge null, da sie wie ein doppelter Schrägstrich ohne Zeichen oder Leerzeichen zwischen den beiden Schrägstrichen aussieht (// ).

Lassen Sie uns auch einige der überflüssigen Zeichen wie []() loswerden das wird nicht benötigt:

[student@studentvm1 testing]$ 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"

Wir haben dem sed vier neue Ausdrücke hinzugefügt Erklärung. Jeder entfernt ein einzelnes Zeichen. Der erste dieser zusätzlichen Ausdrücke ist etwas anders, da die linke eckige Klammer ([ ) Zeichen kann den Beginn einer Menge markieren. Wir müssen die geschweiften Klammern maskieren, um sicherzustellen, dass sed interpretiert es korrekt als reguläres Zeichen und nicht als Sonderzeichen.

Aufräumen mit awk

Wir könnten sed verwenden um die führenden Leerzeichen aus einigen Zeilen zu entfernen, aber der awk Befehl kann dies tun, ordnen Sie die Felder bei Bedarf neu an und fügen Sie den <> hinzu Zeichen um die E-Mail-Adresse:

[student@studentvm1 testing]$ 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">"}'

Das awk Utility ist eigentlich eine mächtige Programmiersprache, die Datenströme auf ihrer STDIN akzeptieren kann. Diese Tatsache macht es in Befehlszeilenprogrammen und Skripten äußerst nützlich.

Das awk Dienstprogramm funktioniert mit Datenfeldern, und das standardmäßige Feldtrennzeichen sind Leerzeichen – beliebig viele Leerzeichen. Der bisher erstellte Datenstrom hat drei durch Leerzeichen getrennte Felder (<first> , <last> , und <email> ):

awk '{print $1" "$2" <"$3">"}'

Dieses kleine Programm nimmt jedes der drei Felder ($1 , $2 , und $3 ) und extrahiert sie ohne führende oder nachgestellte Leerzeichen. Es druckt sie dann nacheinander und fügt zwischen jedem ein einzelnes Leerzeichen sowie den <> ein Zeichen, die zum Einschließen der E-Mail-Adresse benötigt werden.

Abschluss

Der letzte Schritt hier wäre, den Ausgabedatenstrom in eine Datei umzuleiten, aber das ist trivial, also überlasse ich es Ihnen, diesen Schritt auszuführen. Es ist nicht unbedingt erforderlich, dass Sie dies tun.

Ich habe das Bash-Programm in einer ausführbaren Datei gespeichert, und jetzt kann ich dieses Programm jederzeit ausführen, wenn ich eine neue Liste erhalte. Einige dieser Listen sind ziemlich kurz, wie die in diesem Beispiel. Andere waren ziemlich lang und enthielten manchmal bis zu mehreren hundert Adressen und viele Zeilen mit "Zeug", die keine Adressen enthalten, die der Liste hinzugefügt werden sollen.

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


Linux
  1. Erste Schritte mit Zsh

  2. Erste Schritte mit ls

  3. Erste Schritte mit Samba für Interoperabilität

  4. Erste Schritte mit SSH unter Linux

  5. Gewusst wie:Erste Schritte mit Ansible

Erste Schritte mit GitHub

Erste Schritte mit Nix Package Manager

Erste Schritte mit systemctl

Erste Schritte mit cPanel

Erste Schritte mit SiteApps

Erste Schritte mit dem Tar-Befehl