Reguläre Ausdrücke in Beispielen
Aus BraLUG-Wiki
(Unterschied zwischen Versionen)
MaD (Diskussion | Beiträge) (Meine "Folien") |
Aktuelle Version vom 1. Februar 2007, 23:11 Uhr
#!/bin/bash ## ## ## ## ## ::,,:: ## ::,,,,;;,, ## GGKKKKDD;; :::: ;;;;KKLL LLKK..iiKKtt ;;DDWWWWjj ## WW##WW##KK :::: ;;ii##DD DD##..tt##LL;;######WWLL ## WW##;;KKWW ;;WWGG :::: ;;;;##DD DD##..tt##LLGG##LL ## WW##DD##WW..DD##tt :::: ,,;;##DD DD##..tt##LLKK##..ii##LL ## WW## LL##jjKKKK :::: ,,;;##DD DD##..tt##LLGG##ttii##LL ## WW##LL####iiKKKK ,, ,,..####ttLL##KKWW##iiii####WW##LL ## KKWWGGWWLL EEEE,,:: ,, ttWWLL..GG####ff iiKK####ff ## :::::::: ,, .. .... ## ::::,, ,,;;LLttttffttttttjj;; ## ,, ,,,,::,,::iiii;;ii;;;;tttt;;::::ii ## ::::,,::::,, ..iiiiiiiiii;;ttiittiiiiii ## :: ## ## Reguläre Ausdrücke in Beispielen ## """""""""""""""""""""""""""""""" ## Markus Dahms <mad@automagically.de> ## ## ############################################################################## ## ## Übersicht: ## # * Unterschiede "basic"-/"extended"-RegExp # * "basic": "\(", "\)", teilweise: "\{", "\}", "\+" # * "extended": "(", ")", "{", "}" # * Verarbeitung erfolgt im Normalfall zeilenorientiert # * Überblick # * spezielle Zeichen: # . beliebiges Zeichen außer Newline # * beliebige Anzahl des Zeiches oder der Gruppe davor # + ein oder mehr Vorkommen -||- # ? ein oder kein Vorkommen -||- # {n,m} n bis m Vorkommen -||- # {n} n Vorkommen -||- # {n,} n oder mehr Vorkommen -||- # ^ Anfang der Zeile bzw. Negation bei "["/"]" # $ Ende der Zeile # [ ] eins der eingeschlossenen Zeichen # ( ) Gruppierung # | das davor oder danach muss passen # \n n-te Gruppe muss so wieder auftauchen # \ Spezialbedeutung des nächsten Zeichens unterbinden # * POSIX-Zeichenklassen ([:klasse:]) # * alnum, alpha, blank, cntrl, digit, graph, lower, print, space # upper, xdigit ############################################################################## ## ## Suchen (egrep) ## # * "grep" sucht nach Mustern in Dateien # * wichtige Optionen (für GNU grep) # * -e sucht nach "basic"-RegExp # * -E sucht nach "extended"-RegExp (enspricht "egrep") # * -v invertiert das Ergebnis # * -q keine Ausgabe, Rückgabewert entscheidend # * -r rekursive Suche # * --color farbliche Markierung (nicht ganz fehlerfrei) # Jedes Vorkommen von "FIXME" oder "TODO" in allen C-Dateien anzeigen egrep '(FIXME|TODO)' *.c # Alle Kommentarzeilen und Leerzeilen einer (Shellscript-)Datei entsorgen egrep -v '^(#|$)' examples.sh # Alle Header-Zeilen aus einer Mailbox egrep '^[A-Z][[:alnum:]-]*: ' mbox # Beispiel vom Scripting-Workshop: Alle Zeilen rausfischen, die mit einem # "r" und mindestens einer Ziffer anfangen svn log -r 1:HEAD --incremental | \ egrep '^r[[:digit:]]+ ' | \ cut -d\| -f 2 | \ sort | \ uniq -c | \ sort -nr # # Aufgaben: # # * aus der Ausgabe von "dmesg" die Zeilen heraussuchen, die mit # "hd*:" oder "sd*:" anfangen, z.B.: # sda: assuming drive cache: write through # hda: cache flushes supported # hdc: media error (bad sector): error=0x30 { LastFailedSense=0x03 } # # * "dmesg"-Ausgabe nach Fehlern durchsuchen # (error, failure, failed, oops...) # # * Alle von der "bash" gesetzten Umgebungsvariablen anzeigen, die # ein Array sind (z.B. BASH_ARGV=(), aber nicht BASH=/bin/bash; # set | egrep '...') # ############################################################################## ## ## Suchen und Ersetzen (sed) ## # * sed: stream editor # * eigene kleine Skriptsprache # * meistgenutztes Konstrukt: "sed -e 's/muster/ersatz/'" # (entspricht ungefähr "perl -e 'while(<>){s/muster/ersatz/;print}'") # * kann auch suchen: "sed -e '/muster/p;d'" # * wichtige Optionen # * -e angegebenes Skript verarbeiten # * -i Dateien direkt bearbeiten, keine Ausgabe auf stdout # * -r "extended"-RegExp, Standard ist "basic" # * -f Skript aus Datei laden # konvertiere alle GIF-Dateien in JPEG-Dateien IFS=$'\n' for file in `ls -1 *.gif`; do convert "$file" "`echo $file | sed -e 's/\.gif$/.png/'`" done # Whitespace-Zeichen am Zeilenanfang und Ende entfernen sed -e 's/^[[:space:]]*//' -e 's/[[:space:]]*$//' < Eingabe.txt > Ausgabe.txt # E-Mail-Adressen verstecken (längere TLDs als .info oder .name?) sed -r \ -e 's/[[:alnum:]_.-]+@[[:alnum:]_.-]+\.[[:alpha:]]{2,4}/VERSTECKT/g' \ < mbox | grep VERSTECKT # # Aufgaben: # # * Tags aus einer HTML-Datei entsorgen # # * allen Nutzern aus der /etc/passwd, die /bin/false als Shell haben, # /tmp/home/$NUTZERNAME als Home-Verzeichnis zuweisen (in eine andere # Datei als /etc/passwd schreiben ;-) # # * in einem Dateinamen (Variable) alle Zeichen, die nicht Buchstaben, # Zahlen oder erlaubte Sonderzeichen sind (".", "-", "%") sind, durch # Unterstrich ersetzen ("_") ############################################################################## ## ## mögliche Lösungen: ## # egrep: dmesg | egrep '^(sd|hd)[a-z]:' dmesg | egrep -i '(error|fail(ure|ed)|oops)' set | egrep '^BASH[[:upper:]_]*=\(' # sed: sed -e 's/<[^>]*>//g' < /etc/firefox/profile/bookmarks.html sed -r \ -e 's#^([^:]+)(:.*:)([^:]+):/bin/false$#\1\2/tmp/home/\1:/bin/false#' \ < /etc/passwd echo $bla | sed -e 's/[^[:alnum:]%-]/_/g'