bongobong
Anmeldungsdatum: 12. Dezember 2008
Beiträge: 1820
Wohnort: Hamburg
|
Hallo, ich habe ein paar Bilddateien umbenannt. Dabei ist mir ein Fehler passiert den ich nun gerne korrigieren möchte. Ich bekomme das alleine jedoch nicht richtig hin. Ich habe folgende Bildnamen A-12345.jpg und 0-12341.jpg. Immer wenn es in einem Dateinamen fünf aufeinanderfolgende Zahlen vor denen ein Bindestrich und davor wieder eine Zahl ist gibt, soll zwischen dem letzten und vorletzten Zeichen ein Unterstrich hinzugefügt werden: A-12345.jpg → A-12345.jpg
A-12341.jpg → A-1234_1.jpg Folgendes habe ich bereits herausgefunden:
\d steht für Zahlen, also benötige ich dies fünf mal: \d\d\d\d\d
Das Zeichen - kann direkt angegeben werden.
Das Zeichen . muss demaskiert werden mit \. da . sonst für alles steht. Also versuchte ich mal
| rename 's/\d-\d\d\d\d\d\./\d-\d\d\d\d_\d\./g' *
→ Unrecognized escape \d passed through at (eval 1) line 1.
|
Die gewünschten Dateinamen werden nun zwar bearbeitet, jedoch erhalte ich A-12341.jpg → d-dddd_d.jpg und eine Warnung. Kann mir hier jemand weiterhelfen? Danke edit:
Man kann scheinbar auch gruppieren mit \d{5} statt \d\d\d\d\d Wie kann man bei regex ursprüngliche Zeichen behalten?
|
misterunknown
Ehemalige
Anmeldungsdatum: 28. Oktober 2009
Beiträge: 4403
Wohnort: Sachsen
|
bongobong schrieb: Die gewünschten Dateinamen werden nun zwar bearbeitet, jedoch erhalte ich A-12341.jpg → d-dddd_d.jpg und eine Warnung.
Dafür brauchst du Backreferences
Kann mir hier jemand weiterhelfen?
Ungetestet:
| rename 's#\(\d-\d{4}\)\([0-9]\)\.#\1_\2#' *
|
Heißt: Alles, was zwischen \( und \) steht, merkt sich die Engine. Gesucht wird nach einer Ziffer, gefolgt von einem Stich, gefolgt von 4 Ziffern. Das ist die erste Gruppe, deren Ergebnisse gespeichert werden. Dann wird geprüft, ob noch eine fünfte Ziffer existiert, gefolgt von einem Punkt. Die fünfte Ziffer wird auch gemerkt. Ersetzt wird das Ganze durch die erste gemerkte Zeichenkette (Ziffer Strich 4 weitere Ziffern) dann ein Unterstich, und dann die zweite gemerkte Zeichenkette (einzelne Ziffer).
|
track
Anmeldungsdatum: 26. Juni 2008
Beiträge: 7174
Wohnort: Wolfen (S-A)
|
Das ganze geht noch eleganter mit Hilfe eines Lookbehind- Ausdrucks, zusätzlich zur Back Reference: track@track:~$ echo -e 'A-12345.jpg\n0-12341.jpg' | perl -pe 's/(?<=\d-\d{4})(\d)\./_\1./'
A-12345.jpg
0-1234_1.jpg ... p.s.: es geht auch ohne Back Reference, wenn man beides, Lookbehind + Lookahead verwendet: track@track:~$ echo -e 'A-12345.jpg\n0-12341.jpg' | perl -pe 's/(?<=\d-\d{4})(?=\d\.)/_/'
A-12345.jpg
0-1234_1.jpg
LG, track
|
bongobong
(Themenstarter)
Anmeldungsdatum: 12. Dezember 2008
Beiträge: 1820
Wohnort: Hamburg
|
misterunknown schrieb: Ungetestet:
| rename 's#\(\d-\d{4}\)\([0-9]\)\.#\1_\2#' *
|
Heißt: Alles, was zwischen \( und \) steht, merkt sich die Engine. Gesucht wird nach einer Ziffer, gefolgt von einem Stich, gefolgt von 4 Ziffern. Das ist die erste Gruppe, deren Ergebnisse gespeichert werden. Dann wird geprüft, ob noch eine fünfte Ziffer existiert, gefolgt von einem Punkt. Die fünfte Ziffer wird auch gemerkt. Ersetzt wird das Ganze durch die erste gemerkte Zeichenkette (Ziffer Strich 4 weitere Ziffern) dann ein Unterstich, und dann die zweite gemerkte Zeichenkette (einzelne Ziffer).
Danke für die Erklärung, um die Abschnitte (Suchen/Ersetzen) zu trennen nimmst du hier also # damit es übersichtlicher ist. Das kenne ich noch von sed. Gruppieren mit demaskierter Klammer. Ok. Wenn ich das nun so eingebe beschwert sich rename jedoch: \1 better written as $1
Mit $1, jedoch ohne Gruppen, hatte ich da zuvor sogar getestet, da kam jedoch eine Meldung ähnlich "kann auf $1 nicht zugreifen da nicht referenziert". Nehme ich statt dessen jedoch das $-Zeichen erhalte ich gar keine Änderung oder Ausgabe, nicht mal mit der -v Option von rename.
| rename -v 's#\(\d-\d{4}\)\([0-9]\)\.#$1_$2#'
|
|
bongobong
(Themenstarter)
Anmeldungsdatum: 12. Dezember 2008
Beiträge: 1820
Wohnort: Hamburg
|
track schrieb: Das ganze geht noch eleganter mit Hilfe eines Lookbehind- Ausdrucks, zusätzlich zur Back Reference: track@track:~$ echo -e 'A-12345.jpg\n0-12341.jpg' | perl -pe 's/(?<=\d-\d{4})(\d)\./_\1./'
A-12345.jpg
0-1234_1.jpg ... p.s.: es geht auch ohne Back Reference, wenn man beides, Lookbehind + Lookahead verwendet: track@track:~$ echo -e 'A-12345.jpg\n0-12341.jpg' | perl -pe 's/(?<=\d-\d{4})(?=\d\.)/_/'
A-12345.jpg
0-1234_1.jpg
LG, track
Danke, dass sieht jetzt aber doch noch etwas komplizierter für mich aus. Habe das "perl" auch nur erwähnt, da in der manpage von rename steht, dass perlexpr (Perl expression) geutzt werden und ich davon ausging, dass diese sich etwas von regulären regulären Ausdrücken unterscheiden ☺
|
track
Anmeldungsdatum: 26. Juni 2008
Beiträge: 7174
Wohnort: Wolfen (S-A)
|
Dies "Lookahead/-behind" - Gedöns erschreckt einen nur auf den ersten Blick. Im Grunde sind das auch nur spezielle Gruppierungen, wie Du sie bisher auch schon hattest. Nur dass sie nicht "verbraucht" (also ersetzt) werden. Dazu haben sie am Anfang die Markierung ( ?= ...) bzw. ( ?<= ...) (für "rückwärts"). Mehr ist es gar nicht. - lies es einfach mal im verlinkten Tutorium nach ! Oder anhand des Beispiels oben, ist es beides gleichwertig: track@track:~$ echo -e 'A-12345.jpg\n0-12341.jpg' | perl -pe 's/(?<=\d-\d{4})(?=\d\.)/_/'
A-12345.jpg
0-1234_1.jpg
track@track:~$ echo -e 'A-12345.jpg\n0-12341.jpg' | perl -pe 's/(\d-\d{4})(\d\.)/\1_\2/'
A-12345.jpg
0-1234_1.jpg LG, track
|
bongobong
(Themenstarter)
Anmeldungsdatum: 12. Dezember 2008
Beiträge: 1820
Wohnort: Hamburg
|
@track Danke, ich bekomme es jedoch mit deinen Beispielen nicht hin. Lasse ich alles vor und inkl. | weg. Ich konnte auch weder in der Hilfe noch in der Manpage etwas zu der Option e bzw. -pe von Perl finden. Lasse ich "e" weg erhalte ich "Datei oder Verzeichnis nicht gefunden". Lasse ich "p" oder alles weg erhalte ich weder Änderung noch Ausgabe.
|
track
Anmeldungsdatum: 26. Juni 2008
Beiträge: 7174
Wohnort: Wolfen (S-A)
|
Das perl -pe ' ... ' ist einfach nur das Gerüst für einen Perl-Einzeiler. Betrachte es zunächst mal einfach als reine Formsache. Den Rest, das was zwischen den 'Hochkommas' steht, kannst Du einfach 1:1 ins Perl- rename übernehmen. Vorsichtshalber vielleicht zum testen evt. mit der Option rename -nv ... dann siehst Du, was es tun würde. LG, track
|
bongobong
(Themenstarter)
Anmeldungsdatum: 12. Dezember 2008
Beiträge: 1820
Wohnort: Hamburg
|
Hallo und Danke Hat etwas gedauert bis ich zum testen gekommen bin, aber es funktioniert nun: | $ ls
A-12341.jpg A-12345.jpg
$ rename -vn 's/(?<=\d-\d{4})(?=\d\.)/_/' *
0-12341.jpg renamed as 0-1234_1.jpg
$ rename -vn 's/(\d-\d{4})(\d\.)/$1_$2/' *
0-12341.jpg renamed as $1_$2jpg
|
Eine Frage noch zum ersten Befehl: Also ich erstelle mit "(?⇐\d-\d{4})" eine Gruppe, welche Namen speichert, die aus einer Zahl, einem Bindestrich und vier Zahlen bestehen. Auch speichere ich eine zweite Gruppe mit "(\d\.)" in der die Zahl gespeichert wird, welche vor dem Punkt kommt. Woher weiß die Funktion nun, dass der Unterstrich zwischen den beiden Gruppen gesetzt werden soll "/_/". Beim zweiten Befehl ist dass ja recht klar.
|
track
Anmeldungsdatum: 26. Juni 2008
Beiträge: 7174
Wohnort: Wolfen (S-A)
|
Nee, beim Lookbefore und Lookbehind wird die Gruppe ja gerade nicht gespeichert und nicht ersetzt. Sondern es wird nur geguckt, ob sie "vor" bzw. "hinter" dem betrachteten Punkt vorhanden ist. Mehr nicht. Und da hier die "betrachtete Gruppe" für beide der selbe (und leer) ist, wird diese leere Gruppe, nämlich genau der (leere) Zwischenraum zwischen dem Ziffernmuster(1) und der letzten Ziffer mit Punkt dahinter(2) durch den Unterstrich ersetzt. LG, track
|
bongobong
(Themenstarter)
Anmeldungsdatum: 12. Dezember 2008
Beiträge: 1820
Wohnort: Hamburg
|
Nach 3 mal lesen verstanden, Danke 👍
|