Einführung von
grep
in Zeilen
filterntr, sed
in Text
ersetzenZum Warmwerden gibts die folgenden Videos.
Video: Bashino - #02: was soll das Ganze & mehr von egrep [5 min]
Video: Bashino - #01 cat und egrep [11 min]
Video: Bashino - #10 mit sed suchen und ersetzen [7 min]
Im (optionalen) Folgevideo #11 Gezieltes Ersetzen mit sed [8 min] wird noch einmal mehr auf sed und reguläre Ausdrücke eingegangen.
Wer immer noch nicht genug hat, kann sich im sed Video von Pedagogy (en) [18 min] noch haufenweise andere “sed magics” anschauen.
Reguläre Ausdrücke sind einer der Grundpfeiler für die konsolengestützte Datenprozessierung. Damit kann man automatisiert und/oder mit wenig Aufwand
grep
), um
sed
)Dabei ist unter “Textmuster” nicht ein exaktes Wort oder dergleichen zu verstehen, sondern eine Suchkodierung, welche Variabilität zulässt.
Als Einsteig ein kleines Beispiel: Wir haben die folgenden Worte
soll gefunden werden | soll nicht gefunden werden |
---|---|
Frida | Fritz |
Erna | Hugo |
Lisa | Lino |
Die einfachste (und am wenigsten flexible) Lösung wäre es, die gesuchten Worte alle als Alternativen hintereinander zu hängen:
Frida|Erna|Lisa
” = wobei “|
” für ein
“ODER” stehtWenn man reguläre Ausdrücke baut, muss man genau schauen, was die gesuchten Wörter (oder Textpassagen) gemeinsam haben. In unserem Fall enden alle gesuchten Namen mit “a”, was wir verwenden können. Was davor für Buchstaben kommen (und wieviele), ist erst einmal unerheblich, um die Worte von den nicht gesuchten zu unterscheiden. Daher könnten wir folgendes verwenden:
.*a
” = wobei “.
” für ein beliebiges
Zeichen (Buchstabe, Ziffer, Leer-, Satzzeichen, …) steht und
“*
” für eine beliebige Anzahl (auch 0) des vorherigen Teils
(also hier “.
”)Das funktioniert, liefert aber ggf. zu viel Variabilität, was ein häufiger Fallstrick bei regulären Ausdrücken ist. Sprich sie sind zu unkonkret. In unserem Fall passt der Ausdruck auch auf: “..a”, “lala”, “Hans-Anna”, … Sie sehen das Problem? Um dieses zu umgehen, könnte man folgende Sachen machen:
.+a
” = wir fordern mit “+
”, dass vor dem
“a” mindestens ein Buchstabe ist[a-zA-Z]+a
” = wir geben in “[]
” ganz
genau an, welche Buchstaben wir erlauben (hier z.B. keine Umlaute)\w+a
” = dazu könnten wir auch eine vordefinierte
character class (hier \w
für Wortbuchstabe) nehmen[A-Z][a-z]*a
” = mit “[A-Z
” sichern wir,
dass der erste Buchstabe grossgeschrieben ist und anschliessend können
(da “*
”) nur Kleinbuchstaben in der Wortmitte seinDas Beispiel zeigt, dass reguläre Ausdrücke ganz allgemein
(“.*a
”) oder sehr präzise (“Frida|Erna|Lisa
”)
sein können. Die Kunst ist es nun, den für die anstehende Aufgabe
passenden regulären Ausdruck zu erdenken. Dazu hilft einem das
beiliegende Cheatsheet, welches man sicher auch in Zukunft immer wieder
heraus holen muss.
Grundlegend unterscheidet man bei regulären Ausdrücken
.
= jedwedes Zeichen[xyz]
= explizite Zeichenliste, hier “x”, “y” und “z”
[3-7]
= 3,4,5,6,7\s
= whitespaces = Leerzeichen, Tabulator, …\d
= digits = Zahlen = [0-9]\w
= (english) word = [A-Za-z0-9_] (keine Umlaute
etc.!)\S
, \D
, .. = alles
“ausser” der entsprechenden Kleinschreibung[^xyz]
= das ^
negiert die explizite Liste
(alles ausser x,y,z)?
= ein oder kein mal+
= mindestens einmal*
= kann mehrfach vorkommen oder gar nicht^
= Zeilenanfang$
= Zeilenende\b
= Wortgrenze, z.B. er\b
matcht nur “er”
am Wortende(..)
= Klammern werden nicht gematcht, sondern sind
Markierungen(Hi|Ku)nz
=
Hinz oder Kunz\1
Rückreferenzierung auf 1., 2., …
vorangehende Gruppe
(.).\1
matcht aha, oho, ana, d.h. erster und
letzter Buchstabe gleichUm regulären Ausdrücken zu entwickeln oder um damit herumzuspielen um Effekte von Änderungen zu beobachten, eigenen sich online regex tester. Diese könnten ihnen u.a. auch beim Bearbeiten der Übungen oder Tests behilflich sein. Ein solcher ist zum Beispiel
grep
= Suche (und Ausgabe) von Zeilen (oder Teilen) die
ein gegebenes Textmuster oder -stück enthalten
-P
” = Perl RegEx Modus = seeehr umfangreicher RegEx
Support (nur im GNU grep verfügbar, siehe unten)-F
” = (fixiertes) Stringmatching (z.B. zur Suche von
RegEx-Syntax in Texten)-E
” = egrep = extended POSIX RegEx matching = Suche
mit standardisierten Ausdrücken-i
” = Gross-Klein-Schreibung egal-c
” = Anzahl der Zeilen, die einen Match
enthalten-v
” = Gegenteilige Ausgabe (inverted), d.h. alle
Zeilen die NICHT matchen-n
” = Zeilennummern-o
” = nur matchig parts (z.B. für reguläre Ausdrücke
wichtig)-A XX
” = matching line und XX nachfolgende Zeilen
ausgeben (append)-B XX
” = wie -A nur für vorangehende Zeilen
(before)-P
” (Perl)
Modus nutzen, da nur so wirklich alle regex-Feature wie
“\
”-based character classes (z.B. “\d
” etc)
verfügbar sind, z.B. grep --help | grep -P "^\s+-\w\W"
$
” etc. im Ausdruck
verwendet wirdApple User aufgepasst: Apple liefert aus
lizenzrechtlichen Gründen das grep
Programm von BSD statt
GNU aus (check via grep --version
). Dieses unterstützt
keine “Perl RegEx” Kodierungen (hat keinen “-P
” Parameter).
Um letzteres zu nutzen, sollten sie GNU
grep
installieren, welches dann als
ggrep
aufrufbar sein wird.
Dieses Online-grep-regex-Tutorial
gibt einen guten Einstieg in die Nutzung von regulären Ausdrücken und
grep
!
tr
= ersetzt/löscht
EINZELbuchstaben/-character (translate)
echo "1,2,3" | tr "," "\n"
ersetzt Kommas mit
Zeilenumbrüchenecho "1,2 3" | tr ", " "\n\n"
ersetzt sowohl Komma als auch
Leerzeichen JEWEILS mit Zeilenumbruch (unabhängig voneinander!)-d
” löscht entsprechende Zeichen, z.B.
echo "Hans-Peter" | tr -d "-"
löscht alle Trennstrichesed
= stream editor = u.a. für beliebige
Textersetzung
s/text/replacement/
” = (ersten) suchen und
ersetzen von Texten (substitute), z.B.
echo "1,2,3" | sed "s/,/ - /"
s/../../g
” = ALLE ersetzen, z.B.
echo "1,2,3" | sed "s/,/ - /g"
s/../../4
” = vierten Treffer (pro Zeile) ersetzens/../../I
” = Gross-/Kleinschreibung ignorieren (ignore
case), z.B. echo "a,A" | sed "s/a/b/Ig"
/Ig
” in “ignore case”
Beispiel-r
” ermöglicht die Verwendung von erweiterten
RegEx Ausdrücken als Suchtext
echo "1. a." | sed "s/[^a]?\./x-ter/g"
echo "a,A" | sed "s/a/b/g; s/A/B/g"
(werden nacheinander
ausgeführt, pro Zeile)echo -e "Zeile 1\nZeile 2" | sed "2 s/i/l/"
echo "1,2,33,4" | tr "," "\n" | sed "2,3 s/./X/"
$
” (“$
” =
Platzhalter für “letzte Zeile”)echo "1,2,3,4" | tr "," "\n" | sed "2,$ s/./X/"
echo -e "#1\n2" | sed -r "/^#/ s/[[:digit:]]/X/"
-r
”, aber sicher ist
sicher! ;) )-n
” verhindert den automatischen output
p
” Befehl (print)echo "1,2,3,4" | tr "," "\n" | sed -n "2 p"
-n
” würde jeder Zeile
standardmässig ausgegeben und die Zweite noch ein zweites mal aufgrund
des print Befehls!)grep
vs. sed
grep
im -P
erl-Modus verfügbaren
character groups (z.B. \d
) werden von
sed
nicht unterstützt
sed -E
(GNU Version) werden aber die POSIX
character classes unterstützt
[]
-regex-Teil eingebettet sein)grep
: das matchen von RegEx-spezifischen Symbolen
sed
:
-E
(EXTENDED REGULAR EXPRESSIONS):
Escapingverhalten wie grep
…
\n
” = LF : Linux (line feed = ASCII 10)\r
” = CR : (altes) MacOs (carriage return = ASCII
13)\r\n
” = CR LF : Windows (DOS)dos2unix
= einfaches Tool um Eingabe von
Windows-Kodierung in Linux-Kodierung umzuwandeln
sudo apt install dos2unix
(ggf. zuvor
noch sudo apt-get update
notwendig, falls Paket noch nicht
verfügbar)Kodierung von Zeilenumbrüchen sorgt immer wieder für Probleme bei Textersetzungen/-formatierung! Daher immer (wieder) dran denken!
Download: PDF Version dieses Tutorials. Erstellt am 25.07.2024.