Reguläre Ausdrücke in Beispielen

Aus BraLUG-Wiki

Wechseln zu: Navigation, Suche


#!/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'
'Persönliche Werkzeuge