05.11.2013 Aufrufe

EasyLinux - Medialinx Shop

EasyLinux - Medialinx Shop

EasyLinux - Medialinx Shop

MEHR ANZEIGEN
WENIGER ANZEIGEN

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

Hurra! Ihre Datei wurde hochgeladen und ist bereit für die Veröffentlichung.

Erfolgreich gespeichert!

Leider ist etwas schief gelaufen!