Technische Praxis der Computersysteme 1
8. Reguläre Ausdrücke, Texteditoren, Automatisierung
Thomas Leitner <thomas.leitner@univie.ac.at>
Fakultät für Mathematik, Universität Wien Wintersemester 2012
Letzte Änderung: 2013-09-20 20:46:08 +0200
Inhalt
Was sind Reguläre Ausdrücke?
Syntax von regulären Ausdrücken Befehle, die reguläre Ausdrücke nutzen Texteditoren
Automatisierung von Aufgaben
Reguläre Ausdrücke
Ein reguläre Ausdruck (kurz Regex oder Regexp) ist eine Zeichenkette, die eine Menge von Zeichenketten beschreibt. D.h. ein regulärer Ausdruck dient zum Finden einer zum ihm passenden Zeichenkette innerhalb einer eventuellen viel längeren Zeichenkette.
Reguläre Ausdrücke werden nicht nur auf der Kommandozeile in einigen Programmen (
bash
,grep
,sed
,awk
,vim
, …) benutzt, sie sind auch in nahezu allen Programmiersprachen (z.B. Ruby, Perl, Java, C, …) verfügbar und sehr hilfreich.Es gibt viele unterschiedliche Implementierungen von regulären Ausdrücken, wir behandeln die Grundsyntax, die praktisch von allen Implementierungen unterstützt wird. Es gibt auch einen POSIX-Standard für reguläre Ausdrücke (siehe
man 7 regex
).Reguläre Ausdrücke - Zeichen
Jedes Zeichen steht grundsätzlich für sich selbst, außer es hat eine spezielle Bedeutung.
Unter anderem haben folgende Zeichen eine spezielle Bedeutung und müssen deshalb mit Hilfe von
\
maskiertwerden:
. * + ? [ ] ( ) | \ ^ $
Das Zeichen
.
(der Punkt) steht für ein beliebiges Zeichen.Reguläre Ausdrücke - Zeichenklassen
Zeichenklassen sind eine Zusammenfassung verschiedener Zeichen, die an genau einer Stelle stehen können, und werden mit Hilfe von eckigen Klammern definiert (z.B.
[abcd]
). Zeichenbereiche können durch einen Bindestrich angegeben werden (z.B.[a-zA-Z0-9]
).Steht an erster Stelle ein Zirkumflex
^
, wird die Zeichenklasse invertiert (d.h. an der Stelle darf jedes Zeichen außer denen in der Zeichenklasse stehen).Es gibt auch vordefinierte Zeichenklassen. Diese können sowohl innerhalb der eckigen Klammern als auch außerhalb verwendet werden, zB.:
\d
→ eine Ziffer (entspricht[0-9]
)\D
→ obige Klasse negiert\w
→ ein alphanumerisches Zeichen oder der Unterstrich (entspricht[a-zA-Z0-9_]
)\W
→ obige Klasse negiert\s
→ „Whitespace“, d.h. Leerzeichen, Tabulator, Zeilenumbruch, Wagenrücklauf, …\S
→ obige Klasse negiertReguläre Ausdrücke - Quantoren
Quantoren geben an, wie oft der Ausdruck vor ihnen wiederholt werden soll:
?
→ Ausdruck kann einmal oder keinmal vorkommen (entspricht{0,1}
)?
→ Ausdruck kann einmal oder keinmal vorkommen (entspricht{0,1}
)+
→ Ausdruck kommt einmal oder mehrmals vor (entspricht{1,}
)*
→ Ausdruck kommt keinmal, einmal oder mehrmals vor (entspricht{0,}
){n}
→ Ausdruck kommt genau n-mal vor{n,}
→ Ausdruck kommt mindestens n-mal vor{,m}
→ Ausdruck kommt maximal m-mal vor{n,m}
→ Ausdruck kommt mindestens n-mal und maximal m-mal vorQuantoren sind gierig, d.h. sie versuchen immer die maximale Anzahl an übereinstimmenden Zeichen zu finden. In vielen Implementierungen kann man ein
?
an einen beliebigen Quantor anhängen, um die Quantoren genügsam zu machen, damit sie die minimale Anzahl an übereinstimmenden Zeichen finden.Reguläre Ausdrücke - Gruppierungen, Referenzen
Ausdrücke kann man mit runden Klammern gruppieren. Will man Ausdrücke gruppieren, um z.B. darauf einen Quantor anzuwenden, ohne die Gruppierung später zu verwenden, so benutzt man
(?:...)
. Das erzeugt eine sogenannte non-capturing Gruppierung.Auf Gruppierungen kann man sich später mit Hilfe von Referenzen beziehen (außer auf die non-capturing Gruppierungen). Für Referenzen benutzt man
\1
,\2
, usw. für die erste Gruppe, die zweite Gruppe usw.Reguläre Ausdrücke - Alternativen, Anker
Es gibt auch die Möglichkeit, den regulären Ausdruck in zwei Alternativen aufzuteilen. Dazu benutzt man
|
. Willman nur einen Teil des Ausdrucks in zwei Alternativen aufteilen, so muss Gruppierungen verwenden.
Zu guter Letzt gibt es sogenannte Anker, die es erlauben, einen regulären Ausdruck an eine bestimmte Stelle zu fixieren:
\A
→ Anfang der Zeichenkette^
→ Anfang der Zeichenkette oder Zeilenanfang (nach Zeilenumbruch)$
→ Ende der Zeichenkette oder Zeilenende (vor Zeilenumbruch)\Z
→ Ende der Zeichenkette (vor optionalen Zeilenumbruch)\z
→ Ender der Zeichenkette\b
→ Wortrand (Wortanfang oder Wortende)\B
→ kein Wortrand (kein Wortanfang und kein Wortende)Reguläre Ausdrücke - Beispiele
Als Beispielzeichenkette verwenden wir folgenden Text:
STRING1 Mozilla/4.0 (compatible; MSIE 5.0; Windows NT; DigExt) STRING2 Mozilla/4.75 [en](X11;U;Linux2.2.16-22 i586)
.*
→ alles\[en\]
→ die Zeichenfolge[en]
[A-Z]+
→ Folgen von Großbuchstaben\w+;\s?
→ Wort, gefolgt von einem Strichpunkt und optionalem Whitespace\d{3,}
→ Ziffernfolgen mit mindestens drei Ziffern(\w)\1
→ doppelte Wortzeichen(l).*?\1
→ das Zeichen „l“, gefolgt von beliebigen Zeichen bis zum nächsten „l“^\w+
→ alle Wörter, die am Zeilenanfang vorkommen\b[a-z]+\b
→ kleingeschriebene Wörteri(ll|bl)[ae]
→ das Zeichen „i“, gefolgt von „ll“ oder „bl“, gefolgt von „a“ oder „e“Siehe auch
man pcresyntax
,man pcrepattern
, Regulärer Ausdruck auf Wikipedia, Online Regex Tester.Befehle (grep)
grep - Zeilen aus Dateien mittels regulärem Ausdruck filtern.
Standardmäßig werden die gefundenen Zeilen ausgegeben, ist konfigurierbar.
Der Rückgabewert ist 0, falls Zeilen gefunden wurden und sonst 1 (bei Fehler 2).
Optionen:
-e
→ erweiterte reguläre Ausdrücke verwenden,-i
→ Groß-/Kleinschreibung ignorieren,-r
→Verzeichnisse rekursiv durcharbeiten,
-n
→ Zeilenummer anzeigen,-H
→ Dateiname anzeigen,-q
→ nichtsausgeben,
--color
→ gefunden Zeichenketten farbig markieren.$ grep root /etc/passwd
root:x:0:0:root:/root:/bin/bash
$ grep '^\w+:x:15' /etc/passwd
$ grep -E '^\w+:x:15' /etc/passwd
»
»
»
»
Befehle (sed)
Textdateien editieren
Ein wichtiges Handwerkszeug auf der Kommandozeile ist ein guter Texteditor.
Nano: Kompakter, einfach zu bedienender Editor. Standard in Ubuntu.
Vi/Vim: Mächtiger, aber gewöhnungsbedürftiger Editor; schnell, relativ alt, gut für Terminals, nahezu überall installiert. Standard in den meisten Linux Distributionen.
Emacs: Ebenfalls sehr mächtiger Editor; programmierbar in Lisp für Erweiterungen; gut für Terminal und GUI.
Der Default-Editor unter Ubuntu kann mit Hilfe des folgenden Befehls geändert werden:
$ sudo update-alternatives --config editor
Textdateien editieren - Nano
Das Interface von Nano besteht aus drei Teilen:
Statuszeile oben
Dem zu editierenden Text in der Mitte
Menü mit Shortcuts unten (
^
steht für die Strg-Taste undM-
für die Alt-Taste) Die wichtigsten Tastenkombinationen:Strg-O
→ Speichern der DateiStrg-X
→ Beenden von NanoStrg-G
→ Hilfe anzeigenTextdateien editieren - Vim
Ursprungsform vi 1976 von Bill Joy geschrieben, aktuelle Version 7.3.
Um Vim zu verstehen muss man wissen, dass er drei Betriebsmodi kennt:
Betrachten: Man kann lesen, suchen, … In diesen Modus kommt man immer, wenn man die Escape-Taste drückt.
Tastendrücke (Buchstaben) sind (Navigations-)befehle!
Editieren: Hier werden Tastendrücke in den Text an der Stelle des Cursors eingefügt.
Markieren („visual“): Es können Bereiche markiert werden und dann Befehle auf diesen Bereichen ausgeführt werden (z.B. Kopieren, Löschen, blockweises Einfügen, …).
Vim besitzt einen eingebauten Übungsmodus, der mit Hilfe des Befehls
vimtutor
gestartet werden kann!thomas:x:1515:1515:thomas,,,:/home/thomas:/bin/bash
sed - Hilfswerkzeug zum Filtern und Transformieren von Text.
Mit Hilfe einer eigenen Skriptsprache kann man Text filtern und transformieren. Das Programm ermöglicht dadurch einen sehr universellen Einsatz.
Optionen:
-e Skript
→ Angabe des Skripts, das benutzt werden soll,-n
→ Ausgabe nur, wenn explizit angegeben,-r
→ erweiterte, reguläre Ausdrücke benutzen.$ grep bash /etc/passwd | sed -ne 's/\/bash$/\/zsh/'
$ grep bash /etc/passwd | sed -ne 's/\/bash$/\/zsh/p' root:x:0:0:root:/root:/bin/zsh
thomas:x:1515:1515:thomas,,,:/home/thomas:/bin/zsh
$ grep bash /etc/passwd | sed -ne '1s/\/bash$/\/zsh/p' root:x:0:0:root:/root:/bin/zsh
thomas:x:1515:1515:thomas,,,:/home/thomas:/bin/bash
$ sed -re '/bin\/(false|sh)/d;1d;s/\/bash$/\/zsh/' /etc/passwd sync:x:4:65534:sync:/bin:/bin/sync
thomas:x:1515:1515:thomas,,,:/home/thomas:/bin/zsh sshd:x:121:65534::/var/run/sshd:/usr/sbin/nologin
$ sed -ne '5,6p' /etc/passwd # einfacher als die Kombination aus head und tail sync:x:4:65534:sync:/bin:/bin/sync
games:x:5:60:games:/usr/games:/bin/sh
Für mehr Informationen und Beispiele siehe
info sed Examples
und sed Einzeiler»
»
»
»
Links: Vim Tips Wiki / Best Vim Tips
Vim - Betrachten
Cursor bewegen:
w
/b
→ Wort vorwärts/rückwärts;e
→ Wortendej
/k
→ Zeile runter/rauf;h
/l
→ Zeichen zurück/vor (oder Pfeiltasten)gg
/G
→ Zum Anfang/Ende des Textes springenBefehle werden kombiniert nach dem Schema „[Zahl=Wiederholungen] Befehl<Objekt>“:
d[i]w
→ Wort löschen,dd
→ ganze Zeile löschen (auchc
für ändern)5dw
→ 5 Wörter löschen,4j
→ 4 Zeilen runteru
→ Undo,Strg-r
→ RedoBenutzen der Kommandozeile mittels
:
(also:
, dann Befehl und Enter-Taste)::<Zahl>
→ Zu Zeilennummer springen,:$
→ Zur letzten Zeile:r <Dateiname>
→ Datei öffnen,:e
→ Neue Datei anlegen:w
→ Speichern,:q
→ Buffer schließen/Beenden:wq
→ Speichern & Beenden,:q!
→ Beenden ohne zu speichern:help
→ Hilfe in neuem „Fenster“/Buffer anzeigenVim - Editieren
Wechseln in den Editier-Modus:
i
→ Einfügen vor dem CursorI
→ Einfügen am Zeilenanfanga
→ Einfügen nach dem CursorA
→ Einfügen am Zeilenender
→ Ein Zeichen ersetzenR
→ Überschreiben ab dem Cursorc
→ Ändern (z.B.c[i]w
→ Wort ändern,cc
→ Zeile ändern)o
/O
→ Neue Zeile nach/vor aktueller Zeile einfügenZurück in Betrachtungsmodus kommt man mit der Escape-Taste, man hält sich normalerweise nur kurz in diesem Editiermodus auf.
Vim - Markieren, Suchen
Mit
v
(Zeichen markieren),V
(Zeilen markieren) oderStrg-V
(Block=Rechteck markieren) wird der visuelle Modus aktiviert:y
→ Bereich kopieren („yank“)d
oderx
→ Bereich löschen/ausschneidenI
/A
→ Text vor/nach Block einfügen Im Betrachtungsmodus:p
/P
→ Kopierten/Ausgeschnitten Text nach/vor Cursor einfügen Suchen und Ersetzen (siehe auch Vim Wikia: Search and replace):/<Zeichenkette>
→ Nach der Zeichenkette suchen,n
/N
vorwärts/rückwärts weitersuchen:%s/muster/ersatz/[g|c]
→ „%“ überall suchen, „n,m“ in Zeilen n bis m suchen, „g“ heißt „auch mehrmals in selber Zeile“, „c“ steht für Bestätigen. Die Zeichenkette ist ein regulärer Ausdruck.Textdateien Editieren - Emacs
Seit 1976 (Richard Stallman), über 1000 Funktionen + Makros. Emacs basiert auf Lisp und kann mit zahlreichen Modulen erweitert werden. Aktuelle Version ist 24.2.
Es gibt keine verschiedenen Modi wie bei Vim, sondern die Strg-Taste (
C-
) und die Alt-Taste (M-
) werden für Befehle genutzt:C-x b
→ Buffer wechseln oder neuen Buffer erzeugen (mehrere gleichzeitig, in mehreren Fenstern)C-x C-f
/C-x C-s
→ Datei öffnen/speichernC-x C-f
/C-x C-s
→ Datei öffnen/speichernC-x C-c
→ Beenden (bei nicht gespeicherten Dateien wird nachgefragt)C-s
/C-r
→ Vorwärts/Rückwärts suchenC-f
/C-b
bzw.M-f
/M-b
→ Ein Zeichen bzw. Wort vorwärts/rückwärtsC-Space
→ Startmarkierung setzenC-w
/M-w
→ Bereich von Startmarkierung bis Cursor ausschneiden/kopierenC-y
→ Kopierten/Ausgeschnittenen Text einfügenC-_
→ UndoDreimaliges Drücken der Escape-Taste bricht eine angefangene Aktion ab.
Automatisierung
Es ist oft notwendig, Befehle zu einem bestimmten Zeitpunkt in der Zukunft auszuführen (z.B. Server wegen Wartungsarbeiten in einem bestimmten Zustand zu versetzen) bzw. regelmäßig auszuführen (z.B. alte Logdateien löschen).
Linux bietet für beide Aufgaben die nötigen Werkzeuge:
Mit Hilfe von
at
kann man unter Linux einen Job (Sammlung von Befehlen) zu einem bestimmten Zeitpunkt ausführen lassen. Dazu wird beim Systemstart der Dämonatd
gestartet, der diese Aufgabe übernimmt.Regelmäßig auszuführende Jobs werden cron-Jobs genannt, nach dem Befehl, der sie ausführt. Auch hierfür wird ein beim Systemstart ausgeführter Dämon benutzt. Es gibt mehrere Implementierungen, unter Ubuntu wird zumeist
vcron
verwendet.Zusätzlich gibt es das Programm
anacron
, welches speziell für Rechner, die nicht 24/7 laufen, gedacht ist und verpasste Jobs beim Booten ausführt.Sowohl at-Jobs als auch cron-Jobs können von normalen (ie. nicht-root) Benutzern genutzt werden.
Automatisierung - cron 1
Die Konfigurationsdateien für cron befinden sich in
/etc/crontab
→ globale Konfigurationsdatei/etc/cron.d/
→ weitere crontab-Konfigurationsdateien/etc/cron.{hourly,daily,weekly,monthly}
→ Jobs, die in bestimmten Intervallen ausgeführt werden sollen/var/spool/cron/crontabs/
→ Konfigurationsdateien für BenutzerEditieren kann man die eigene Konfigurationsdateien mittels
crontab -e
. Die Anzeige der eigenen Konfigurationsdatei erfolgt mittelscrontab -l
.Beispiele für crontab-Einträge:
# Befehl zur Minute 5 jeder Stunde ausführen 5 * * * * /bin/bash /path/to/some/script.sh
# Befehl um 17 Uhr an jedem Wochentag (Mo-Fr) ausführen 0 17 * * 1-5 mail -s "Go home!" thomas.leitner@univie.ac.at Automatisierung - cron 2
Format für crontab-Dateien (siehe auch
man 5 crontab
):* * * * * auszuführender Befehl
| | | | |
| | | | +--- Tag der Woche (0 - 6) (Sonntag ist 0)
| | | +--- Monat (1 - 12)
| | +--- Tag des Monats (1 - 31)
| +--- Stunde (0 - 23) +--- Minute (0 - 59)
Die Zeitangaben können einzelne Zahlen (12), Bereiche mit optionalen Schrittweiten (1-5/2) oder Listen (1,3-5,7) sein. Die Angabe von * ist gleichbedeutend mit Anfang-Ende (also der Bereich, der alles abdeckt).
In der globalen Konfigurationsdatei kommt vor dem Befehl noch der Benutzername, mit dem der Befehl ausgeführt werden soll.
Automatisierung - Befehle (at)
Copyright und Lizenz
Copyright: Thomas Leitner thomas.leitner@univie.ac.at
Basiert teilweise auf den Folien von Harald Schilly harald.schilly@univie.ac.at Lizenz: Creative Commons CC BY-NC-SA
„Namensnennung-Keine kommerzielle Nutzung-Weitergabe unter gleichen Bedingungen 3.0 Österreich.“ - http://creativecommons.org/licenses/by-nc-sa/3.0/at/
at - Erlaubt das Ausführen von Jobs zu einem bestimmten Zeitpunkt.
Syntax:
at [Optionen] Zeitangabe
Die Befehle eines Jobs werden entweder von der Standardeingabe (mit EOF –
CTRL+d
– beenden) oder von einer Datei gelesen; und später mittels/bin/sh
ausgeführt.Die Zeitangabe ist sehr flexibel (z.B.
13:15 tomorrow
,10am Jul 31 2013
,now + 1min
).Optionen:
-f Datei
→ Datei mit Befehlen,-l
→ anhängende Jobs auflisten,-r Job
→ Job mittels Jobnummer löschen,-c Job
→ Befehls des Jobs ausgeben$ at now + 1min
warning: commands will be executed using /bin/sh at> echo "created file" > created
at> <EOT>
job 3 at Tue Nov 20 12:01:00 2012
$ at -l
3 Tue Nov 20 12:01:00 2012 a thomas
$ ls -l created; sleep 1m; ls -l created
ls: cannot access created: No such file or directory -rw-rw-r-- 1 thomas thomas 13 Nov 20 12:01 created
»
»
»
»
»