Einführung
Ein regulärer Ausdruck beschreibt Text anhand seiner Struktur und nicht anhand einer einzigen exakt vorgegebenen Zeichenfolge. Dieselbe Mustersprache kommt in vielen Linux-Werkzeugen zum Einsatz, aber jedes Werkzeug verwendet sie auf eigene Weise: grep wählt Treffer aus oder extrahiert sie, sed transformiert einen Datenstrom und awk kombiniert Muster mit feldbezogenen Aktionen.
Sie beginnen mit Ankern und Zeichenklassen, gehen anschließend zu erweiterten Wiederholungen und zur Extraktion über, sehen sich Transformationen vor dem Speichern an und schließen mit der Feldauswahl und Aggregation ab. Die Muster werden in Anführungszeichen gesetzt, damit die Shell Sonderzeichen an das Textwerkzeug übergibt, anstatt sie selbst zu interpretieren.
Zeilen mit grundlegender Regex-Struktur vergleichen
In diesem Schritt verwenden Sie literalen Text, Anker und Zeichenklassen, um Positionen in vollständigen Zeilen zu beschreiben.
Sehen Sie sich die Übungsdatei an:
cd /home/labex/project/regex-lab
nl -ba contacts.txt
Literaler Text wird an jeder Position innerhalb einer Zeile gefunden:
grep 'active' contacts.txt
^ verankert ein Muster am Anfang, $ am Ende einer Zeile. Suchen Sie den Datensatz von Alice sowie Datensätze, die mit einer zweistelligen Zahl enden:
grep '^Alice|' contacts.txt
grep '[0-9][0-9]$' contacts.txt
Innerhalb eckiger Klammern entspricht eine Zeichenklasse genau einem Zeichen. [ABC] bedeutet A, B oder C:
grep '^[ABC]' contacts.txt | tee abc-contacts.txt
Damit werden Alice, Bob und Carol ausgegeben. Speichern Sie auch die verankerten Treffer mit Zahlen:
grep '[0-9][0-9]$' contacts.txt > two-digit-values.txt
Erweiterte reguläre Ausdrücke verwenden und Treffer extrahieren
In diesem Schritt verwenden Sie erweiterte reguläre Ausdrücke für Alternativen und Wiederholungen. Anschließend extrahieren Sie nur den passenden Teil der Zeichenfolge.
grep -E aktiviert Operatoren wie + (ein oder mehrere), ? (null oder eines) und | (Alternative). Suchen Sie vollständige Statusfelder mit active oder pending:
cd /home/labex/project/regex-lab
grep -E '\|(active|pending)\|' contacts.txt
Ein E-Mail-ähnliches Muster lässt sich aus mehreren Teilen aufbauen:
[[:alnum:]._-]+findet mindestens ein zulässiges Zeichen im lokalen Teil;@ist ein wörtliches Zeichen;[[:alnum:].-]+findet den Hauptteil der Domain;\.[[:alpha:]]{2,}findet einen Punkt und ein Suffix aus mindestens zwei Buchstaben.
Verwenden Sie -o, um nur die passenden Teilzeichenfolgen auszugeben:
grep -Eo '[[:alnum:]._-]+@[[:alnum:].-]+\.[[:alpha:]]{2,}' contacts.txt | tee emails.txt
Nummerieren Sie die passenden Zeilen und zählen Sie die extrahierten Adressen:
grep -En '\|(active|pending)\|' contacts.txt
wc -l < emails.txt | tr -d ' ' > email-count.txt
cat email-count.txt
dave_at_example.com entspricht dem Muster nicht, weil das Zeichen @ fehlt.
Transformationen mit Sed anzeigen
In diesem Schritt transformieren Sie einen Datenstrom mit sed, ohne die Eingabedatei zu verändern.
Eine Ersetzung hat die Form s/pattern/replacement/flags. Ersetzen Sie zunächst nur das erste a in jeder Zeile und anschließend jedes kleingeschriebene a mit dem Flag g:
cd /home/labex/project/regex-lab
sed 's/a/A/' contacts.txt
sed 's/a/A/g' contacts.txt
Verwenden Sie ein anderes Trennzeichen, wenn der Text selbst Schrägstriche enthält oder ein anderes Trennzeichen übersichtlicher ist. Ersetzen Sie die E-Mail-Domains durch redacted.invalid:
sed -E 's#@[[:alnum:].-]+\.[[:alpha:]]{2,}#@redacted.invalid#g' contacts.txt
Mit Sed-Adressen wählen Sie aus, auf welche Zeilen ein Befehl angewendet wird. Ersetzen Sie den Status nur in Zeilen, die ein exaktes Feld |inactive| enthalten:
sed '/|inactive|/s/|inactive|/|disabled|/' contacts.txt | tee contacts-preview.txt
Überprüfen Sie, dass die Originaldatei weiterhin inactive enthält:
grep '|inactive|' contacts.txt
Mit Sed eine bereinigte Datei erstellen
In diesem Schritt kombinieren Sie mehrere Sed-Befehle und speichern den transformierten Datenstrom in einer neuen Datei.
Die Kopfzeile in services.csv soll unverändert bleiben. Normalisieren Sie in den Datenzeilen warn zu warning und fügen Sie an das letzte numerische Feld das Suffix ms an. Mit -e geben Sie mehrere Befehle an. Die Adresse 2,$ beschränkt deren Anwendung auf die Zeilen 2 bis zum Ende:
cd /home/labex/project/regex-lab
sed -E -e '2,$ s/,warn,/,warning,/' -e '2,$ s/([0-9]+)$/\1ms/' services.csv | tee services-clean.csv
Die Klammern erfassen die letzten Ziffern, und \1 verwendet diese Erfassung in der Ersetzung erneut.
Vergleichen Sie die ursprüngliche und die neue Datei:
diff -u services.csv services-clean.csv || true
Der Status ungleich null von diff ist hier zu erwarten, weil die Ausgabe absichtlich geändert wurde. || true ermöglicht, dass eine kopierte Befehlssequenz fortgesetzt wird.
Mit Awk Felder auswählen und aggregieren
In diesem Schritt verwenden Sie awk, wenn eine Aufgabe sowohl eine Feldstruktur als auch Berechnungen erfordert.
-F, legt das Komma als Eingabetrenner fest. Geben Sie nur für Datenzeilen den Dienst und den Status aus. NR enthält die Nummer des aktuellen Datensatzes:
cd /home/labex/project/regex-lab
awk -F, 'NR > 1 {print $1, $2}' services.csv
Wählen Sie Zeilen aus, deren numerisches drittes Feld größer als 200 ist:
awk -F, 'NR > 1 && $3 > 200 {print $1, $3}' services.csv | tee slow-services.txt
Addieren Sie eine Gesamtsumme und zählen Sie die Datensätze. Berechnen Sie anschließend im END-Block den Durchschnitt. Mit printf steuern Sie das Zahlenformat:
awk -F, 'NR > 1 {sum += $3; count++} END {printf "average_latency=%.1f\n", sum/count}' services.csv | tee latency-summary.txt
Awk-Muster bestimmen, für welche Datensätze eine Aktion ausgeführt wird. Felder wie $1 und $3 machen strukturierte Berechnungen übersichtlich.
Zusammenfassung
Sie haben Regex-Muster aus Ankern, Zeichenklassen, Alternativen und Wiederholungen erstellt, mit grep Treffer ausgewählt und extrahiert, mit sed Transformationen angezeigt und gespeichert sowie mit awk eine feldbezogene Auswahl und Aggregation durchgeführt. In der nächsten Challenge wenden Sie diese Konzepte an, ohne eine vollständige Befehlsfolge vorgegeben zu bekommen.



