Der Versuch, im Perl-Umbenennungs-Tool (Debian) zu rechnen


8

Nehmen wir an, ich habe fünf MP3-Dateien:

01-trackfoo.mp3
02-trackbar.mp3
03-trackbaz.mp3
04-trackabc.mp3
05-trackxyz.mp3

Jetzt höre ich mir die Dateien kurz an (nur mplayer auf der Konsole reicht aus) und stelle fest, dass die Titel in der falschen Reihenfolge sind . 05 ist eigentlich 02 und der Rest muss umbenannt werden. Also werde ich zuerst eine temporäre Umbenennung durchführen:

01-trackfoo.mp3

02-trackbar.mp3
03-trackbaz.mp3
04-trackabc.mp3
00-trackxyz.mp3

Jetzt brauchen wir eine "Verschiebung": 02 sollte 03 werden, 03 sollte 04 werden und 04 sollte 05 werden. Um Verwirrung zu minimieren, wird ex-05 (jetzt 00) erst später mvbearbeitet.

Mein Ansatz war folgender: (Perl rename, von Larry Wall, Standard hier bei Debian)

rename 's/0([2-4])([\s\S]+)/0($1+1)$2/' *

sowie (später, nach etwas mehr RTFM'ing)

rename 's/0([2-4])([\s\S]+)/0($1+1)$2/e' *

Keiner von ihnen hat funktioniert, insbesondere weil der /e[val]Modifikator nichts anderes als Auswertungen akzeptiert und einen Fehler auslöst, sobald Sie versuchen, die Auswertungen mit Zeichenfolgen zu kombinieren. Das bashkann es ganz gut, zB foo$((1+6))wird ausgewertet foo7.

Wie kann ich das tun (einzeilig bevorzugt, nicht beabsichtigt, ein ganzes eigenständiges Skript nur dafür zu schreiben)?

Antworten:


7

Du hattest es fast. Sie müssen nur /eLiteralzeichenfolgen und Zeichenfolgenverkettung innerhalb der modifizierten Ersetzung mithilfe von Anführungszeichen und dem Punktoperator explizit machen .

rename 's/0([2-4])([\s\S]+)/"0".($1+1).$2/e' *

Das Original 05 bleibt noch nicht umbenannt, aber +1 für die Behebung des Einzeiler- Fehlers.
Peter.O

1
(kleiner Hinweis, Umbenennen heißt in Ubuntu Vorname ) ... Wenn keine Namen im Verzeichnis mit $'\x01'2einer vorläufigen Umbenennung wie dieser beginnen: prename 's/^05/\x012/' 05*.. dann die obige [2-4]Umbenennung .. dann reicht ein Finale aus prename 's/^\x01/0/' $'\x01'2*.. Das macht 3 eins -liners ... Für eine vierte und eine erste Überprüfung auf das mögliche Vorhandensein einer Datei, die mit beginnt $'\x01', wird so etwas wie dieses Bash- Snippet es shopt -s nullglob; x=($'\x01'*); [[ -n $x ]] && { echo '\x01' is not suitable; exit; }
einfangen

JA! Vielen Dank, Alan, ich habe nicht an diesen Punktoperator gedacht, obwohl ich wusste, was ich mit lesbaren Worten tun sollte: "Sag / e, ich soll das Zeug außerhalb von () nicht berühren " :) Und danke an Peter für die Bash Ansatz auch. Wenn ich eine Vorstellung davon gehabt hätte, wie nah die PHP-Syntax an der von Perl ist, hätte ich die Lösung wahrscheinlich durch Ausprobieren gefunden. Weil dieser Punkt das JavaScript-Gegenstück '+' in PHP für die Verkettung von Zeichenfolgen ist.
Syntaxfehler

4

Einzeiler bevorzugt, nicht die Absicht, ein ganzes eigenständiges Skript nur dafür zu schreiben

Wenn die Dinge so kompliziert werden, sehe ich keinen Grund, kein Skript zu schreiben. Sie werden sich nie daran erinnern, wie dies von einem Lauf zum nächsten zu tun ist, also werden Sie es entweder jedes Mal neu erfinden oder es trotzdem in ein Skript packen.

Für eine kleine Sache wie diese versuche ich im Allgemeinen, sie in Bash zu lösen:

#!/bin/bash
if [ -z "$1" ] ; then echo Need arguments. ; exit 1 ; fi

typeset -i i=1
for f in "$*"
do
    tailbits=`echo "$f" | sed -e 's/^[0-9]+//'`
    mv "$f" sertmp-`printf %02d $i`"$tailbits"
    i=i+1
done

for f in "sertmp-*"
do
    mv "$f" `echo "$f" | sed -e s/^sertmp-//` 
done

Grundsätzlich entfernt dieses Skript alle führenden Ziffern und setzt dann eine mit Nullen aufgefüllte, zunehmende Seriennummer auf die Vorderseite, wobei die Dateien in der Reihenfolge nummeriert sind, in der Sie sie an das Skript übergeben.

Dies geschieht in zwei Schritten mit sertmp-Präfixen für den ersten Durchgang, um das Risiko von Namenskollisionen zu vermeiden. Wenn Sie dieses Skript mp3-renameraufrufen und es wie folgt aufrufen:

$ mp3-renamer 01-foo.mp3 03-bar.mp3 04-qux.mp3

Beim ersten Umbenennen kommt es zu einer trivialen Kollision, wenn Sie für die Umbenennung nicht zwei Durchgänge verwenden. ( 01-foo.mp3-> 01-foo.mp3.)

Wenn Sie es aber so nennen:

$ mp3-renamer 02-foo.mp3 01-foo.mp3

Sie löschen versehentlich 01-foo.mp3beim ersten Umbenennen mit einem 1-Pass-Umbenennen.

Wenn das Problem komplizierter wird, würde ich es in Perl umschreiben. Zu diesem Zeitpunkt könnten Sie dann einen Hash verwenden, um die Zuordnung von alten und neuen Namen zu speichern, und mit ein wenig cleverem Code die richtige Reihenfolge für die Umbenennungen ermitteln, um die Notwendigkeit von zwei Durchgängen zu vermeiden.

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.