EasyLinux - Medialinx Shop
EasyLinux - Medialinx Shop
EasyLinux - Medialinx Shop
Sie wollen auch ein ePaper? Erhöhen Sie die Reichweite Ihrer Titel.
YUMPU macht aus Druck-PDFs automatisch weboptimierte ePaper, die Google liebt.
Workshop<br />
Automatisieren<br />
.*‐[0‐9][0‐9]?.[0‐9][0‐9]?.20..‐.*<br />
Abb. 2: Dateien komplex umbenennen und verschieben – dafür benötigen Sie ein Bash-<br />
Skript, das mit regulären Ausdrücken arbeitet.<br />
teiname gespeichert ist, der dem obigen Muster<br />
entspricht, also die Form Vorne-DD.MM.<br />
JJJJ-Hinten hat, wobei DD ein ein- oder zweistelliger<br />
Tag, MM ein ebenso ein- oder zweistelliger<br />
Monat und JJJJ ein vierstelliges Jahr<br />
(zwischen 2000 und 2099) ist. Das Muster ist<br />
so einfach wie möglich gehalten, passt also<br />
auch auf fehlerhafte Datumsangaben wie den<br />
35.13.2012.<br />
MUSTER='\(.*\)‐\([0‐9][0‐9]\?\)\U<br />
.\([0‐9][0‐9]\?\)\.\(20..\)‐\(.*U<br />
\)'<br />
VORNE=$( echo $NAME | sed ‐e "sU<br />
|$MUSTER|\1|" )<br />
TAG=$( echo $NAME | sed ‐e "sU<br />
|$MUSTER|\2|" )<br />
MONAT=$( echo $NAME | sed ‐e "sU<br />
|$MUSTER|\3|" )<br />
JAHR=$( echo $NAME | sed ‐e "sU<br />
|$MUSTER|\4|" )<br />
HINTEN=$( echo $NAME | sed ‐e "sU<br />
|$MUSTER|\5|" )<br />
test $TAG ‐le 9 && TAG=0$TAG<br />
test $MONAT ‐le 9 && MONAT=0$MONAT<br />
Reguläre Ausdrücke<br />
Die erste Zeile weist der Shell-Variablen $MUS-<br />
TER einen regulären Ausdruck zu. Er enthält<br />
etliche Backslashes (Rückwärts-Schrägstriche<br />
„\“), die ihn unleserlich machen. In einer vereinfachten<br />
(und nicht funktionierenden) Darstellung<br />
hat der Ausdruck diese Form:<br />
Listing 1: Verschieben mit reg. Ausdrücken<br />
for NAME in *‐{[1‐9],[0‐3][0‐9]}.{[1‐9],[01][0‐9]}.20??*; do<br />
if test "${NAME:0:1}" != '*'; then<br />
MUSTER='\(.*\)‐\([0‐9][0‐9]\?\)\.\([0‐9][0‐9]\?\)\.\(20..\)\?\(.*\)'<br />
VORNE=$( echo $NAME | sed ‐e "s|$MUSTER|\1|" )<br />
TAG=$( echo $NAME | sed ‐e "s|$MUSTER|\2|" )<br />
MONAT=$( echo $NAME | sed ‐e "s|$MUSTER|\3|" )<br />
JAHR=$( echo $NAME | sed ‐e "s|$MUSTER|\4|" )<br />
HINTEN=$( echo $NAME | sed ‐e "s|$MUSTER|\5|" )<br />
test $TAG ‐le 9 && TAG=0$TAG<br />
test $MONAT ‐le 9 && MONAT=0$MONAT<br />
test $HINTEN = "‐" && HINTEN=""<br />
mkdir ‐p $JAHR/$MONAT<br />
mv "$NAME" "$JAHR/$MONAT/$JAHR‐$MONAT‐$TAG‐$VORNE$HINTEN"<br />
echo $NAME '‐‐>' $JAHR/$MONAT/$JAHR‐$MONAT‐$TAG‐$VORNE$HINTEN<br />
fi<br />
done<br />
Die einzelnen Teile dieses Ausdrucks haben<br />
die folgenden Bedeutungen:<br />
l .*: Der Punkt steht für ein beliebiges Zeichen,<br />
und der Stern dahinter bedeutet, dass<br />
es beliebig oft (auch nie) auftreten darf.<br />
l -: Das ist einfach das Minuszeichen, das<br />
in den Beispieldateinamen vor und hinter<br />
dem Datum steht.<br />
l [0-9]: Wie bei den einfacheren Mustern,<br />
welche die Shell versteht (s. o.), steht [0-<br />
9] für eine der Ziffern zwischen 0 und 9.<br />
l [0-9]?: Das angehängte Fragezeichen ändert<br />
diesen Teilausdruck ab; es bewirkt,<br />
dass hier entweder eines der Zeichen 0 bis<br />
9 oder nichts erwartet wird. (Zusammengefasst<br />
steht also [0-9][0-9]? für eine einoder<br />
zweistellige Zahl.)<br />
l 20..: Dies ist schließlich das vereinfachte<br />
Muster für eine mit 20 beginnende vierstellige<br />
(Jahres-)Zahl (wobei 20.. auch auf<br />
die Zeichenkette 20th passt).<br />
In dieser Darstellung tauchen Punkte in zwei<br />
Bedeutungen auf: einmal als beliebiges Zeichen<br />
und einmal als echter Punkt (im Datum<br />
zwischen Tag und Monat sowie zwischen Monat<br />
und Jahr). Aus diesem Grund verwendet<br />
der korrekte reguläre Ausdruck die Darstellung<br />
\. für einen „echten“ Punkt. Auch das<br />
Fragezeichen muss mit einem Backslash versehen<br />
werden. Beachtet man diese Regeln, ergibt<br />
sich der folgende Ausdruck:<br />
.*‐[0‐9][0‐9]\?\.[0‐9][0‐9]\?\.2U<br />
0..‐.*<br />
Er ähnelt dem endgültigen Ausdruck schon<br />
stärker. Was jetzt noch fehlt, sind die zahlreichen<br />
öffnenden und schließenden runden<br />
Klammern \(…\), welche Teilausdrücke einklammern.<br />
Dadurch kann man später die so<br />
erkannten Teile separat ansprechen, als „ersten<br />
geklammerten Ausdruck“, „zweiten geklammerten<br />
Ausdruck“ usw., in der Notation<br />
regulärer Ausdrücke mit \1, \2 usw.<br />
Wenn es nur darum ginge, die Jahreszahl aus<br />
dem Dateinamen herauszuholen, würde es<br />
ausreichen, diesen Teilausdruck in Klammern<br />
zu setzen, also so:<br />
.*‐[0‐9][0‐9]\?\.[0‐9][0‐9]\?\.\U<br />
(20..\)‐.*<br />
Da aber auch die restlichen Teile benötigt<br />
werden, gibt es hier insgesamt fünf Teilausdrücke<br />
(Namensteil vor dem Datum, Tag, Monat,<br />
Jahr, Namensteil nach dem Datum), die<br />
durch Klammern markiert werden.<br />
Die Befehle hinter der Musterdefinition rufen<br />
alle das Kommando sed auf, das reguläre<br />
72 www.easylinux.de<br />
<strong>EasyLinux</strong> 04/2012