Linux Professional Institute Learning Logo.
Weiter zum Inhalt
  • Home
    • Alle Ressourcen
    • LPI Lernmaterialien
    • Mitmachen
    • Publishing Partner
    • Publishing Partner werden
    • Über uns
    • FAQ
    • Mitwirkende
    • Roadmap
    • Kontakt
  • LPI.org
103.7 Lektion 2
Thema 101: Systemarchitektur
101.1 Hardwareeinstellungen ermitteln und konfigurieren
  • 101.1 Lektion 1
101.2 Das System starten
  • 101.2 Lektion 1
101.3 Runlevel wechseln und das System anhalten oder neu starten
  • 101.3 Lektion 1
Thema 102: Linux-Installation und -Paketverwaltung
102.1 Festplattenaufteilung planen
  • 102.1 Lektion 1
102.2 Einen Bootmanager installieren
  • 102.2 Lektion 1
102.3 Shared Libraries verwalten
  • 102.3 Lektion 1
102.4 Debian-Paketverwaltung verwenden
  • 102.4 Lektion 1
102.5 RPM und YUM-Paketverwaltung verwenden
  • 102.5 Lektion 1
102.6 Linux als Virtualisierungs-Gast
  • 102.6 Lektion 1
Thema 103: GNU- und Unix-Befehle
103.1 Auf der Befehlszeile arbeiten
  • 103.1 Lektion 1
  • 103.1 Lektion 2
103.2 Textströme mit Filtern verarbeiten
  • 103.2 Lektion 1
103.3 Grundlegende Dateiverwaltung
  • 103.3 Lektion 1
  • 103.3 Lektion 2
103.4 Ströme, Pipes und Umleitungen verwenden
  • 103.4 Lektion 1
  • 103.4 Lektion 2
103.5 Prozesse erzeugen, überwachen und beenden
  • 103.5 Lektion 1
  • 103.5 Lektion 2
103.6 Prozess-Ausführungsprioritäten ändern
  • 103.6 Lektion 1
103.7 Textdateien mit regulären Ausdrücken durchsuchen
  • 103.7 Lektion 1
  • 103.7 Lektion 2
103.8 Grundlegendes Editieren von Dateien
  • 103.8 Lektion 1
Thema 104: Geräte, Linux-Dateisysteme, Filesystem Hierarchy Standard
104.1 Partitionen und Dateisysteme anlegen
  • 104.1 Lektion 1
104.2 Die Integrität von Dateisystemen sichern
  • 104.2 Lektion 1
104.3 Das Mounten und Unmounten von Dateisystemen steuern
  • 104.3 Lektion 1
104.5 Dateizugriffsrechte und -eigentümerschaft verwalten
  • 104.5 Lektion 1
104.6 Symbolische und Hardlinks anlegen und ändern
  • 104.6 Lektion 1
104.7 Systemdateien finden und Dateien am richtigen Ort plazieren
  • 104.7 Lektion 1
How to get certified
  1. Thema 103: GNU- und Unix-Befehle
  2. 103.7 Textdateien mit regulären Ausdrücken durchsuchen
  3. 103.7 Lektion 2

103.7 Lektion 2

Zertifikat:

LPIC-1

Version:

5.0

Thema:

103 GNU- und Unix-Befehle

Lernziel:

103.7 Textdateien mit regulären Ausdrücken durchsuchen

Lernziel:

2 von 2

Einführung

Das Streaming von Daten durch eine Kette von Pipelinebefehlen ermöglicht die Anwendung von zusammengesetzten Filtern auf der Grundlage regulärer Ausdrücke. Reguläre Ausdrücke sind eine wichtige Technik, die nicht nur in der Systemadministration, sondern auch im Data-Mining und verwandten Bereichen eingesetzt wird. Zwei Befehle eignen sich besonders für die Manipulation von Dateien und Textdaten mit regulären Ausdrücken: grep und sed. grep ist ein Musterfinder und sed ein Streameditor. Sie sind für sich allein nützlich, aber gerade in Zusammenarbeit mit anderen Prozessen stechen sie besonders hervor.

Der Musterfinder: grep

Eine der häufigsten Anwendungen von grep ist die Erleichterung der Inspektion größerer Dateien, wobei reguläre Ausdrücke als Filter auf jede Zeile angewendet werden. Er kann verwendet werden, um nur die Zeilen anzuzeigen, die mit einem bestimmten Begriff beginnen. Zum Beispiel kann grep verwendet werden, um eine Konfigurationsdatei für Kernelmodule zu untersuchen, wobei nur Optionszeilen aufgelistet werden:

$ grep '^options' /etc/modprobe.d/alsa-base.conf
options snd-pcsp index=-2
options snd-usb-audio index=-2
options bt87x index=-2
options cx88_alsa index=-2
options snd-atiixp-modem index=-2
options snd-intel8x0m index=-2
options snd-via82xx-modem index=-2

Das Pipezeichen | kann verwendet werden, um die Ausgabe eines Befehls direkt auf die Eingabe von grep umzuleiten. Das folgende Beispiel verwendet einen Klammerausdruck, um Zeilen aus der Ausgabe von fdisk -l auszuwählen, beginnend mit Disk /dev/sda oder Disk /dev/sdb:

# fdisk -l | grep '^Disk /dev/sd[ab]'
Disk /dev/sda: 320.1 GB, 320072933376 bytes, 625142448 sectors
Disk /dev/sdb: 7998 MB, 7998537728 bytes, 15622144 sectors

Die bloße Auswahl von Zeilen mit Übereinstimmungen ist möglicherweise für eine bestimmte Aufgabe nicht geeignet und erfordert Anpassungen des Verhaltens von grep durch seine Optionen. Zum Beispiel weist die Option -c oder --count grep an, um darzustellen, wie viele Zeilen eine Übereinstimmungen enthalten:

# fdisk -l | grep '^Disk /dev/sd[ab]' -c
2

Die Option kann vor oder nach dem regulären Ausdruck stehen. Andere wichtige Optionen von grep sind:

-c oder --count

Anstatt die Suchergebnisse anzuzeigen, wird nur die Gesamtzahl angezeigen, wie oft eine Übereinstimmung in einer bestimmten Datei auftritt.

-i oder --ignore-case

Beachten bei der Suche nicht die Groß-/Kleinschreibung.

-f FILE oder --file=FILE

Gibt die Datei an, welche den zu verwendenden regulären Ausdruck enthält.

-n oder --line-number

Zeigt die Nummer der übereinstimmenden Zeile an.

-v oder --invert-match

Wählt jede Zeile aus, mit Ausnahme der Zeilen, die eine Übereinstimmungen enthalten.

-H oder --with-filename

Veranlasst die Ausgabe des Namens der Datei, welche die übereinstimmende Zeile enthält.

-z oder --null-data

Statt grep Ein- und Ausgabedatenströme als getrennte Zeilen zu behandeln (standardmäßig per Zeilenumbruch), wird die Ein- oder Ausgabe als eine Folge von Zeilen angenommen. Wenn die Ausgabe des Befehls find unter Verwendung seiner Option -print0 mit dem Befehl grep kombiniert wird, sollte die Option -z oder --null-data verwendet werden, um den Datenstrom auf die gleiche Weise zu verarbeiten.

Obwohl standardmäßig aktiviert, wenn mehrere Dateipfade als Eingabe angegeben werden, ist die Option -H für einzelne Dateien nicht aktiviert. Das kann in besonderen Situationen nachteilhaft sein, wie z.B. wenn grep direkt von find aufgerufen wird:

$ find /usr/share/doc -type f -exec grep -i '3d modeling' "{}" \; | cut -c -100
artistic aspects of 3D modeling. Thus this might be the application you are
This major approach of 3D modeling has not been supported
oce is a C++ 3D modeling library. It can be used to develop CAD/CAM softwares, for instance [FreeCad

In diesem Beispiel listet find jede Datei unter /usr/share/doc auf und übergibt sie dann an grep, das wiederum eine nicht-sensitive Suche nach 3D modeling innerhalb der Datei durchführt. Die Pipe zu cut ist nur dazu da, die Ausgabelänge auf 100 Spalten zu begrenzen. Beachten Sie jedoch, dass es keine Möglichkeit gibt, herauszufinden, aus welcher Datei die Zeilen stammen. Dieses Problem wird durch Hinzufügen von -H zu grep behoben:

$ find /usr/share/doc -type f -exec grep -i -H '3d modeling' "{}" \; | cut -c -100
/usr/share/doc/openscad/README.md:artistic aspects of 3D modeling. Thus this might be the applicatio
/usr/share/doc/opencsg/doc/publications.html:This major approach of 3D modeling has not been support

Jetzt ist es möglich, die Dateien zu identifizieren, in denen eine Übereinstimmung gefunden wurde. Um die Auflistung noch aussagekräftiger zu gestalten, können übereinstimmende Zeilen mit führenden und abschließenden Zeilen versehen werden:

$ find /usr/share/doc -type f -exec grep -i -H -1 '3d modeling' "{}" \; | cut -c -100
/usr/share/doc/openscad/README.md-application Blender), OpenSCAD focuses on the CAD aspects rather t
/usr/share/doc/openscad/README.md:artistic aspects of 3D modeling. Thus this might be the applicatio
/usr/share/doc/openscad/README.md-looking for when you are planning to create 3D models of machine p
/usr/share/doc/opencsg/doc/publications.html-3D graphics library for Constructive Solid Geometry (CS
/usr/share/doc/opencsg/doc/publications.html:This major approach of 3D modeling has not been support
/usr/share/doc/opencsg/doc/publications.html-by real-time computer graphics until recently.

Die Option -1 weist grep an, eine Zeile davor und eine Zeile danach einzufügen, wenn es eine Zeile mit einer Übereinstimmung findet. Diese zusätzlichen Zeilen werden Kontextzeilen genannt und in der Ausgabe durch ein Minuszeichen hinter dem Dateinamen gekennzeichnet. Das gleiche Ergebnis kann mit -C 1 oder --context=1 erzielt werden, und es können auch andere Kontextzeilenmengen angegeben werden.

Es gibt zwei ergänzende Programme zu grep: egrep und fgrep. Das Programm egrep ist äquivalent zum Befehl grep -E, der neben den einfachen regulären Ausdrücken weitere Funktionen beinhaltet. Zum Beispiel ist es mit egrep möglich, Funktionen erweiterter regulärer Ausdrücke, wie Verzweigungen, zu verwenden:

$ find /usr/share/doc -type f -exec egrep -i -H -1 '3d (modeling|printing)' "{}" \; | cut -c -100
/usr/share/doc/openscad/README.md-application Blender), OpenSCAD focuses on the CAD aspects rather t
/usr/share/doc/openscad/README.md:artistic aspects of 3D modeling. Thus this might be the applicatio
/usr/share/doc/openscad/README.md-looking for when you are planning to create 3D models of machine p
/usr/share/doc/openscad/RELEASE_NOTES.md-* Support for using 3D-Mouse / Joystick / Gamepad input dev
/usr/share/doc/openscad/RELEASE_NOTES.md:* 3D Printing support: Purchase from a print service partne
/usr/share/doc/openscad/RELEASE_NOTES.md-* New export file formats: SVG, 3MF, AMF
/usr/share/doc/opencsg/doc/publications.html-3D graphics library for Constructive Solid Geometry (CS
/usr/share/doc/opencsg/doc/publications.html:This major approach of 3D modeling has not been support
/usr/share/doc/opencsg/doc/publications.html-by real-time computer graphics until recently.

In diesem Beispiel wird entweder 3D modeling oder 3D printing mit dem Ausdruck übereinstimmen, Groß-/Kleinschreibung wird nicht berücksichtigt. Um nur die Teile eines Textstroms anzuzeigen, die mit dem von egrep verwendeten Ausdruck übereinstimmen, verwenden Sie die Option -o.

Das Programm fgrep ist äquivalent zu grep -F, was bedeutet das es keine regulären Ausdrücke parst. Es ist nützlich bei einfachen Suchvorgängen, bei denen das Ziel darin besteht, einen wörtlichen Ausdruck zu finden. Daher werden Sonderzeichen wie das Dollarzeichen und der Punkt in einem regulären Ausdruck wörtlich und nicht nach ihrer Bedeutung interpretiert.

Der Streameditor: sed

Der Zweck des Programms sed besteht darin, textbasierte Daten auf nicht-interaktive Weise zu modifizieren. Das bedeutet, dass die gesamte Bearbeitung durch vordefinierte Anweisungen erfolgt und nicht durch willkürliches Eintippen direkt in einen auf dem Bildschirm angezeigten Text. In moderner Hinsicht kann sed als ein Vorlagenparser verstanden werden: einem Text als Eingabe übergeben, platziert es benutzerdefinierte Inhalte an vordefinierten Positionen oder an Stellen, welche eine Übereinstimmung mit einem regulären Ausdruck aufweisen.

Sed eignet sich, wie der Name schon sagt, gut für Text, der durch Pipelines geleitet wird. Seine grundlegende Syntax lautet sed -f SCRIPT, wenn Editieranweisungen in der Datei SCRIPT gespeichert sind, oder sed -e COMMANDS, um COMMANDS direkt von der Kommandozeile auszuführen. Wenn weder -f noch -e verwendet werden, benutzt sed den ersten Nichtoptionsparameter als Skriptdatei. Es ist auch möglich, eine Datei als Eingabe zu verwenden, indem man einfach den Pfad als Argument an sed übergibt.

Anweisungen von sed bestehen aus einem einzigen Zeichen, dem möglicherweise eine Adresse vorangestellt ist oder auf das eine oder mehrere Optionen folgen, und werden auf jede Zeile einzeln angewendet. Adressen können eine einzelne Zeilennummer, ein regulärer Ausdruck oder ein Bereich von Zeilen sein. Zum Beispiel kann die erste Zeile eines Textstroms mit 1d gelöscht werden, wobei 1 die Zeile angibt, auf die der Löschbefehl d angewendet wird. Um die Verwendung von sed zu verdeutlichen, verwenden wir die Ausgabe des Befehls factor `seq 12`, der die Primfaktoren für die Zahlen 1 bis 12 zurückgibt:

$ factor `seq 12`
1:
2: 2
3: 3
4: 2 2
5: 5
6: 2 3
7: 7
8: 2 2 2
9: 3 3
10: 2 5
11: 11
12: 2 2 3

Das Löschen der ersten Zeile mit sed wird durch 1d erreicht:

$ factor `seq 12` | sed 1d
2: 2
3: 3
4: 2 2
5: 5
6: 2 3
7: 7
8: 2 2 2
9: 3 3
10: 2 5
11: 11
12: 2 2 3

Ein Zeilenbereich kann mit einem Trennkomma angegeben werden:

$ factor `seq 12` | sed 1,7d
8: 2 2 2
9: 3 3
10: 2 5
11: 11
12: 2 2 3

In der gleichen Ausführung kann mehr als eine Anweisung, getrennt durch Semikolons, verwendet werden. In diesem Fall ist es jedoch wichtig, diese mit Anführungszeichen zu umschließen, damit das Semikolon nicht von der Shell interpretiert wird:

$ factor `seq 12` | sed "1,7d;11d"
8: 2 2 2
9: 3 3
10: 2 5
12: 2 2 3

In diesem Beispiel wurden zwei Löschbefehle ausgeführt, zuerst auf Zeilen von 1 bis 7 und dann auf Zeile 11. Eine Adresse kann auch ein regulärer Ausdruck sein, so dass nur Zeilen mit einer Übereinstimmung von der Anweisung betroffen sind:

$ factor `seq 12` | sed "1d;/:.*2.*/d"
3: 3
5: 5
7: 7
9: 3 3
11: 11

Der reguläre Ausdruck :.*2.* stimmt mit jedem Vorkommen der Zahl 2 irgendwo nach einem Doppelpunkt überein, was zur Löschung von Zeilen führt, welche die Zahlen 2 als Faktor enthalten. Mit sed wird alles, was zwischen Schrägstrichen (/) steht, als regulärer Ausdruck betrachtet, und standardmäßig werden alle einfachen RE unterstützt. Zum Beispiel zeigt sed -e "/^#/d" /etc/services den Inhalt der Datei /etc/services ohne die Zeilen, die mit # (Kommentarzeilen) beginnen. Der Löschbefehl d ist nur einer der vielen Editierbefehle, die von sed zur Verfügung gestellt werden. Anstatt eine Zeile zu löschen, kann sed sie durch einen bestimmten Text ersetzen:

$ factor `seq 12` | sed "1d;/:.*2.*/c REMOVED"
REMOVED
3: 3
REMOVED
5: 5
REMOVED
7: 7
REMOVED
9: 3 3
REMOVED
11: 11
REMOVED

Die Anweisung c REMOVED ersetzt einfach eine Zeile durch den Text REMOVED. Im Fall des Beispiels ist jede Zeile mit einer Teilzeichenkette, die dem regulären Ausdruck :.*2.* entspricht, von der Anweisung c REMOVED betroffen. Die Anweisung a TEXT kopiert den mit TEXT bezeichneten Text in eine neue Zeile nach der Zeile mit einer Übereinstimmung. Die Anweisung r FILE tut dasselbe, kopiert aber den Inhalt der mit FILE bezeichneten Datei. Die Anweisung w bewirkt das Gegenteil von r, d.h. die Zeile wird an die angegebene Datei angehängt.

Die bei weitem am häufigsten verwendete Anweisung an sed ist s/FIND/REPLACE/, die verwendet wird, um eine Übereinstimmung mit dem regulären Ausdruck FIND durch den Text REPLACE zu ersetzen. Beispielsweise ersetzt die Anweisung s/hda/sda/ eine Teilzeichenkette, die dem wörtlichem RE hda entspricht, durch sda. Nur die erste Übereinstimmung, die in der Zeile gefunden wird, wird ersetzt, es sei denn, die Flagge g (global) wird nach der Anweisung gesetzt, wie in s/hda/sda/g.

Ein realistisches Anwendungsbeispiel wird helfen, die Merkmale von sed zu veranschaulichen. Nehmen wir an, eine medizinische Klinik möchte Textnachrichten an ihre Kunden senden, um diese an ihre geplanten Termine für den nächsten Tag zu erinnern. Ein typisches Implementierungsszenario stützt sich auf einen professionellen Sofortnachrichtendienst, der eine API für den Zugriff auf das für die Zustellung der Nachrichten zuständige System bereitstellt. Diese Nachrichten stammen in der Regel aus demselben System, in dem die Anwendung läuft, welche die Termine des Kunden steuert, ausgelöst durch eine bestimmte Tageszeit oder ein anderes Ereignis. In dieser hypothetischen Situation könnte die Anwendung eine Datei namens appointments.csv erzeugen, die tabellarische Daten mit allen Terminen für den nächsten Tag enthält, die dann von sed verwendet werden, um die Textnachrichten aus einer Vorlagendatei namens template.txt zu rendern. CSV-Dateien sind eine Standardmethode, um Daten aus Datenbankabfragen zu exportieren, daher könnten Beispieltermine wie folgt vorliegen:

$ cat appointments.csv
"NAME","TIME","PHONE"
"Carol","11am","55557777"
"Dave","2pm","33334444"

Die erste Zeile enthält die Beschriftungen für jede Spalte, die verwendet werden, um die Tags innerhalb der Beispielvorlagendatei abzugleichen:

$ cat template.txt
Hey <NAME>, don't forget your appointment tomorrow at <TIME>.

Die Kleiner-als- < und Größer-als- > Zeichen wurden um Marker herum angebracht, um diese als Tags zu identifizieren. Das folgende Bash-Skript parst alle Termine in der Warteschlange und verwendet template.txt als Nachrichtenvorlage:

#! /bin/bash

TEMPLATE=`cat template.txt`
TAGS=(`sed -ne '1s/^"//;1s/","/\n/g;1s/"$//p' appointments.csv`)
mapfile -t -s 1 ROWS < appointments.csv
for (( r = 0; r < ${#ROWS[*]}; r++ ))
do
  MSG=$TEMPLATE
  VALS=(`sed -e 's/^"//;s/","/\n/g;s/"$//' <<<${ROWS[$r]}`)
  for (( c = 0; c < ${#TAGS[*]}; c++ ))
  do
    MSG=`sed -e "s/<${TAGS[$c]}>/${VALS[$c]}/g" <<<"$MSG"`
  done
  echo curl --data message=\"$MSG\" --data phone=\"${VALS[2]}\" https://mysmsprovider/api
done

Ein tatsächliches Produktionsskript würde auch die Authentifizierung, Fehlerprüfung und Protokollierung handhaben, aber das Beispiel verfügt zunächst nur über grundlegende Funktionen. Die ersten Anweisungen, die von sed ausgeführt werden, werden nur auf die erste Zeile angewendet — die Adresse 1 in 1s/^"//;1s/","/\n/g;1s/"$//p — um die führenden und abschließenden Anführungszeichen zu entfernen — 1s/^"// und 1s/"$// — und um Feldtrennzeichen durch ein Zeilenumbruchszeichen zu ersetzen: 1s/","/\n/g. Nur die erste Zeile wird für das Laden von Spaltennamen benötigt, so dass nicht übereinstimmende Zeilen durch die Option -n unterdrückt werden, was erfordert, dass das Flag p nach dem letzten sed-Kommando gesetzt wird, um die übereinstimmende Zeile auszugeben. Die Tags werden dann in der Variablen TAGS als ein Bash-Array gespeichert. Eine weitere Bash-Array-Variable wird durch den Befehl mapfile erzeugt, um die Zeilen, die die Termine enthalten, in der Array-Variablen ROWS zu speichern.

Eine for-Schleife wird verwendet, um jede Terminzeile, die in ROWS gefunden wird, zu verarbeiten. Dann werden Anführungszeichen und Trennzeichen im Termin — der Termin steht in der Variable ${ROWS[$r]}, die als Here String verwendet wird — durch sed ersetzt, ähnlich wie die Befehle, die zum Laden der Tags verwendet werden. Die getrennten Werte für den Termin werden dann in der Array-Variablen VALS gespeichert, wobei die Array-Indizes 0, 1 und 2 den Werten für NAME, TIME und PHONE entsprechen.

Schließlich läuft eine verschachtelte for-Schleife durch das TAGS-Array und ersetzt jedes in der Vorlage gefundene Tag durch seinen entsprechenden Wert in VALS. Die Variable MSG enthält eine Kopie der gerenderten Vorlage, die bei jedem Schleifendurchlauf durch TAGS mittels dem Ersetzungsbefehl s/<${TAGS[$c]}>/${VALS[$c]}/g aktualisiert wird.

Das Ergebnis ist eine gerenderte Botschaft: "Hey Carol, don’t forget your appointment tomorrow at 11am." Die gerenderte Nachricht kann dann als Parameter durch eine HTTP-Anforderung mit curl, als E-Mail-Nachricht oder eine ähnliche Methode versendet werden.

Kombination von grep und sed

Die Befehle grep und sed können zusammen verwendet werden, wenn komplexeres Text Mining erforderlich ist. Als Systemadministrator möchte man z. B. alle Anmeldeversuche an einem Server untersuchen. Die Datei /var/log/wtmp zeichnet alle An- und Abmeldungen auf, während die Datei /var/log/btmp die fehlgeschlagenen Anmeldeversuche aufzeichnet. Diese werden im Binärformat abgelegt, welches mit den Befehlen last bzw. lastb gelesen werden kann.

Die Ausgabe von lastb zeigt nicht nur den beim fehlgeschlagenen Anmeldeversuch verwendeten Benutzernamen, sondern auch dessen IP-Adresse:

# lastb -d -a -n 10 --time-format notime
user     ssh:notty       (00:00)     81.161.63.251
nrostagn ssh:notty       (00:00)     vmd60532.contaboserver.net
pi       ssh:notty       (00:00)     132.red-88-20-39.staticip.rima-tde.net
pi       ssh:notty       (00:00)     132.red-88-20-39.staticip.rima-tde.net
pi       ssh:notty       (00:00)     46.6.11.56
pi       ssh:notty       (00:00)     46.6.11.56
nps      ssh:notty       (00:00)     vmd60532.contaboserver.net
narmadan ssh:notty       (00:00)     vmd60532.contaboserver.net
nominati ssh:notty       (00:00)     vmd60532.contaboserver.net
nominati ssh:notty       (00:00)     vmd60532.contaboserver.net

Die Option -d übersetzt die IP-Nummer in den entsprechenden Hostnamen. Der Hostname kann Hinweise auf den ISP oder den Hostingdienst liefern, der für diese fehlerhaften Anmeldeversuche verwendet wurde. Die Option -a setzt den Hostnamen in die letzte Spalte, was die noch auszuführende Filterung erleichtert. Die Option --time-format notime unterdrückt die Zeit, zu der der Anmeldeversuch stattfand. Der Befehl lastb kann einige Zeit in Anspruch nehmen, wenn es zu viele fehlerhafte Anmeldeversuche gab, daher wurde die Ausgabe mit der Option -n 10 auf zehn Einträge begrenzt.

Nicht allen Remote-IPs ist ein Hostname zugeordnet, so dass Reverse-DNS nicht auf diese anwendbar ist und verworfen werden können. Obwohl man einen regulären Ausdruck benutzen könnte, der mit dem erwarteten Format für einen Hostnamen am Ende der Zeile übereinstimmt, ist es wahrscheinlich einfacher, einen regulären Ausdruck zu schreiben, der entweder mit einem Buchstaben aus dem Alphabet oder mit einer einzelnen Ziffer am Ende der Zeile übereinstimmt. Das folgende Beispiel zeigt, wie der Befehl grep die Ausgabe an seiner Standardeingabe entgegen nimmt und die Zeilen ohne Hostnamen entfernt:

# lastb -d -a --time-format notime | grep -v '[0-9]$' | head -n 10
nvidia   ssh:notty       (00:00)     vmd60532.contaboserver.net
n_tonson ssh:notty       (00:00)     vmd60532.contaboserver.net
nrostagn ssh:notty       (00:00)     vmd60532.contaboserver.net
pi       ssh:notty       (00:00)     132.red-88-20-39.staticip.rima-tde.net
pi       ssh:notty       (00:00)     132.red-88-20-39.staticip.rima-tde.net
nps      ssh:notty       (00:00)     vmd60532.contaboserver.net
narmadan ssh:notty       (00:00)     vmd60532.contaboserver.net
nominati ssh:notty       (00:00)     vmd60532.contaboserver.net
nominati ssh:notty       (00:00)     vmd60532.contaboserver.net
nominati ssh:notty       (00:00)     vmd60532.contaboserver.net

Der Befehl grep mit der Option -v zeigt nur die Zeilen an, die nicht mit dem angegebenen regulären Ausdruck übereinstimmen. Ein regulärer Ausdruck, der auf eine beliebige Zeile passt, die mit einer Zahl endet (d. h. [0-9]$), erfasst nur die Einträge ohne einen Hostnamen. Daher zeigt grep -v '[0-9]$' nur die Zeilen an, die mit einem Hostnamen enden.

Die Ausgabe kann noch weiter gefiltert werden, indem nur der Domainname behalten und die anderen Teile aus jeder Zeile entfernt werden. Der Befehl sed kann dies mit einem Ersetzungsbefehl tun, um die gesamte Zeile durch einen Rückverweis auf den darin enthaltenen Domänennamen zu ersetzen:

# lastb -d -a --time-format notime | grep -v '[0-9]$' | sed -e 's/.* \(.*\)$/\1/' | head -n 10
vmd60532.contaboserver.net
vmd60532.contaboserver.net
vmd60532.contaboserver.net
132.red-88-20-39.staticip.rima-tde.net
132.red-88-20-39.staticip.rima-tde.net
vmd60532.contaboserver.net
vmd60532.contaboserver.net
vmd60532.contaboserver.net
vmd60532.contaboserver.net
vmd60532.contaboserver.net

Die geschützte Klammer in .* \(.*\)$ weist sed an, sich diesen Teil der Zeile zu merken, d. h. den Teil zwischen dem letzten Leerzeichen und dem Ende der Zeile. Im Beispiel wird dieser Teil mit \1 referenziert und zum Ersetzen der gesamten Zeile verwendet.

Es ist klar, dass die meisten entfernten Hosts versuchen, sich mehr als einmal anzumelden, daher wiederholt sich derselbe Domänenname. Um die wiederholten Einträge zu unterdrücken, muss zunächst sortiert werden (mit dem Befehl sort) und dann an den Befehl uniq übergeben werden:

# lastb -d -a --time-format notime | grep -v '[0-9]$' | sed -e 's/.* \(.*\)$/\1/' | sort | uniq | head -n 10
116-25-254-113-on-nets.com
132.red-88-20-39.staticip.rima-tde.net
145-40-33-205.power-speed.at
tor.laquadrature.net
tor.momx.site
ua-83-226-233-154.bbcust.telenor.se
vmd38161.contaboserver.net
vmd60532.contaboserver.net
vmi488063.contaboserver.net
vmi515749.contaboserver.net

Dies zeigt, wie verschiedene Befehle kombiniert werden können, um das gewünschte Ergebnis zu erzielen. Die Hostnamenliste kann dann verwendet werden, um blockierende Firewall-Regeln zu schreiben oder andere Maßnahmen zu ergreifen, um die Sicherheit des Servers zu verbessern.

Geführte Übungen

  1. Der Befehl last zeigt eine Liste der zuletzt eingeloggten Benutzer, einschließlich ihrer Herkunfts-IPs. Wie würde der Befehl egrep verwendet werden, um die Ausgabe von last so zu filtern, das nur die genannte IPv4-Adresse anzeigt wird und alle zusätzlichen Informationen in der entsprechenden Zeile verwirft?

  2. Welche Option sollte an grep übergeben werden, um die Ausgabe, die durch den mit der Option -print0 ausgeführten Befehl find erzeugt wird, korrekt zu filtern?

  3. Der Befehl uptime -s zeigt das letzte Datum an, an dem das System eingeschaltet wurde, wie in 2019-08-05 20:13:22. Was wird das Ergebnis des Befehls uptime -s | sed -e 's/(.*) (.*)/\1/' sein?

  4. Welche Option sollte man grep geben, damit es übereinstimmende Zeilen zählt, anstatt diese anzuzeigen?

Offene Übungen

  1. Die Grundstruktur einer HTML-Datei beginnt mit den Elementen html, head und body, zum Beispiel:

    <html>
    <head>
      <title>News Site</title>
    </head>
    <body>
      <h1>Headline</h1>
      <p>Information of interest.</p>
    </body>
    </html>

    Beschreiben Sie, wie Adressen in sed verwendet werden könnten, um nur das Element body und seinen Inhalt anzuzeigen.

  2. Welcher sed-Ausdruck entfernt alle Tags aus einem HTML-Dokument, wobei nur der gerenderte Text erhalten bleibt?

  3. Dateien mit der Erweiterung .ovpn sind sehr beliebt, um VPN-Clients zu konfigurieren, da sie nicht nur die Einstellungen, sondern auch den Inhalt von Schlüsseln und Zertifikaten für den Client enthalten. Diese Schlüssel und Zertifikate befinden sich ursprünglich in separaten Dateien, so dass sie in die Datei .ovpn kopiert werden müssen. Es folgt ein Auszug aus einer .ovpn-Vorlage:

    client
    dev tun
    remote 192.168.1.155 1194
    <ca>
    ca.crt
    </ca>
    <cert>
    client.crt
    </cert>
    <key>
    client.key
    </key>
    <tls-auth>
    ta.key
    </tls-auth>

    Angenommen, die Dateien ca.crt, client.crt, client.key und ta.key befinden sich im aktuellen Verzeichnis, wie würde die Template-Konfiguration durch sed modifiziert werden, um jeden Dateinamen durch seinen Inhalt zu ersetzen?

Zusammenfassung

Diese Lektion behandelt die beiden wichtigsten Linuxbefehle im Zusammenhang mit regulären Ausdrücken: grep und sed. Skripte und zusammengesetzte Befehle stützen sich auf grep und sed, um eine breite Palette von Textfilter- und Parsingaufgaben auszuführen. Die Lektion behandelt die folgenden Schritte:

  • Wie man grep und seine Variationen wie egrep und fgrep verwendet.

  • Wie man sed und seine internen Anweisungen zur Textmanipulation verwendet.

  • Beispiele für Anwendungen regulärer Ausdrücke mit grep und sed.

Lösungen zu den geführten Übungen

  1. Der Befehl last zeigt eine Liste der zuletzt eingeloggten Benutzer, einschließlich ihrer Herkunfts-IPs. Wie würde der Befehl egrep verwendet werden, um die Ausgabe von last so zu filtern, das nur die genannte IPv4-Adresse anzeigt wird und alle zusätzlichen Informationen in der entsprechenden Zeile verwirft?

    last -i | egrep -o '[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}'

  2. Welche Option sollte an grep übergeben werden, um die Ausgabe, die durch den mit der Option -print0 ausgeführten Befehl find erzeugt wird, korrekt zu filtern?

    Die Option -z oder --null-data, wie in find . -print0 | grep -z expression.

  3. Der Befehl uptime -s zeigt das letzte Datum an, an dem das System eingeschaltet wurde, wie in 2019-08-05 20:13:22. Was wird das Ergebnis des Befehls uptime -s | sed -e 's/(.*) (.*)/\1/' sein?

    Es wird ein Fehler auftreten. Standardmäßig sollten Klammern escaped werden, um Rückverweise in sed zu verwenden.

  4. Welche Option sollte man grep geben, damit es übereinstimmende Zeilen zählt, anstatt diese anzuzeigen?

    Option -c.

Lösungen zu den offenen Übungen

  1. Die Grundstruktur einer HTML-Datei beginnt mit den Elementen html, head und body, zum Beispiel:

    <html>
    <head>
      <title>News Site</title>
    </head>
    <body>
      <h1>Headline</h1>
      <p>Information of interest.</p>
    </body>
    </html>

    Beschreiben Sie, wie Adressen in sed verwendet werden könnten, um nur das Element body und seinen Inhalt anzuzeigen.

    Um nur body zu zeigen, sollten die Adressen /<body>/,/<\/body>/ lauten, wie in sed -n -e '/<body>/,/<\/body>/p'. Die Option -n wird sed anweisen, dass standardmäßig keine Zeilen ausgegeben werden, daher der Befehl p am Ende des Ausdrucks von sed, um übereinstimmende Zeilen dennoch auszugeben.

  2. Welcher sed-Ausdruck entfernt alle Tags aus einem HTML-Dokument, wobei nur der gerenderte Text erhalten bleibt?

    Der sed-Ausdruck s/<[^>]*>//g ersetzt jeden in <> eingeschlossenen Inhalt durch eine leere Zeichenkette.

  3. Dateien mit der Erweiterung .ovpn sind sehr beliebt, um VPN-Clients zu konfigurieren, da sie nicht nur die Einstellungen, sondern auch den Inhalt von Schlüsseln und Zertifikaten für den Client enthalten. Diese Schlüssel und Zertifikate befinden sich ursprünglich in separaten Dateien, so dass sie in die Datei .ovpn kopiert werden müssen. Es folgt ein Auszug aus einer .ovpn-Vorlage:

    client
    dev tun
    remote 192.168.1.155 1194
    <ca>
    ca.crt
    </ca>
    <cert>
    client.crt
    </cert>
    <key>
    client.key
    </key>
    <tls-auth>
    ta.key
    </tls-auth>

    Angenommen, die Dateien ca.crt, client.crt, client.key und ta.key befinden sich im aktuellen Verzeichnis, wie würde die Template-Konfiguration durch sed modifiziert werden, um jeden Dateinamen durch seinen Inhalt zu ersetzen?

    Der Befehl

    sed -r -e 's/(^[^.]*)\.(crt|key)$/cat \1.\2/e' < client.template > client.ovpn

    ersetzt jede Zeile, die mit .crt oder .key endet, durch den Inhalt einer Datei, deren Name gleich der Zeile lautet. Die Option -r weist sed an, erweiterte reguläre Ausdrücke zu verwenden, während e am Ende des Ausdrucks sed anweist, Übereinstimmungen durch die Ausgabe des Befehls cat \1.\2 zu ersetzen. Die Rückverweise \1 und \2 entsprechen dem Dateinamen und der Dateiendung, die in der Übereinstimmung gefunden wurden.

Linux Professional Insitute Inc. Alle Rechte vorbehalten. Besuchen Sie die LPI Learning Website: https://learning.lpi.org
Dieses Werk steht unter der Lizenz Creative Commons Attribution-NonCommercial-NoDerivatives 4.0 International.

Nächste Lektion

103.8 Grundlegendes Editieren von Dateien (103.8 Lektion 1)

Nächste Lektion lesen

Linux Professional Insitute Inc. Alle Rechte vorbehalten. Besuchen Sie die LPI Learning Website: https://learning.lpi.org
Dieses Werk steht unter der Lizenz Creative Commons Attribution-NonCommercial-NoDerivatives 4.0 International.

LPI ist eine Non-Profit-Organisation.

© 2022 Linux Professional Institute (LPI) ist eine globale Organisation für Zertifizierungsstandards und zur Karriereplanung für Open-Source-Profis. Mit mehr als 200.000 Zertifikatsinhabern ist es die weltweit erste und größte herstellerneutrale Linux- und Open-Source-Zertifizierungsstelle. LPI verfügt über zertifizierte Fachleute in über 180 Ländern, bietet Prüfungen in mehreren Sprachen an und hat Hunderte von Trainingspartnern.

Unser Ziel ist es, wirtschaftliche und kreative Möglichkeiten für alle zu ermöglichen, indem wir Open-Source-Wissens- und Kompetenzzertifizierungen allgemein zugänglich machen.

  • LinkedIn
  • flogo-RGB-HEX-Blk-58 Facebook
  • Twitter
  • Kontaktieren Sie uns
  • Datenschutz und Cookie-Richtlinien

Haben Sie einen Fehler entdeckt oder möchten Sie helfen, diese Seite zu verbessern? Lassen Sie es uns wissen.

© 1999–2022 The Linux Professional Institute Inc. Alle Rechte vorbehalten.