Musterbasiertes Umbenennen der Batch-Datei im Terminal

48

Ich muss Folgendes umbenennen:

file_001_loremipsum.png
file_002_dolor.png
file_003_sit.png
file_004_amet.png
file_105_randomness.png

in

upl_loremipsum.png
upl_dolor.png
upl_sit.png
upl_amet.png
upl_randomness.png

Wie mache ich das mit nur einer einfachen Zeile des Terminalbefehls?

Unamata Sanatarai
quelle
1
Eine ausfallsichere, auf Regex basierende Python-Version, die in allen Unterordnern rekursiv funktioniert: stackoverflow.com/a/39698169/191246
ccpizza

Antworten:

79

Die Lösung für das obige Beispiel mit Umbenennen :

rename -v -n 's/file_\d{1,3}/upl/' file_*.png

Verwendungszweck:

rename [options] [Perl regex search/replace expression] [files]

Von man rename:

   -v, --verbose
           Verbose: print names of files successfully renamed.
   -n, --no-act
           No Action: show what files would have been renamed.

Umbenennen kann Regex als Argumente nehmen.

Was wir betrachten, ist der Inhalt zwischen den einzelnen Anführungszeichen '. Sie können Regex getrennt durch platzieren /.

Formel: s/(1)/(2)/wobei (1)= Suchmuster und (2)= Muster ersetzen.

So vertraut youself mit regex und Muster basierte Batch - Datei umbenennen genießen!

Unamata Sanatarai
quelle
14
Ich weiß, dass dies Ubuntu ist, aber wenn jemand hier landet, obwohl er nach einer OS X-Lösung gesucht hat (ich habe es getan), lässt renamees sich leicht mit installieren brew install rename.
Sandstrom
In Ubuntu 18.10 ist das --no-actFlag --nonostattdessen. Diese Antwort könnte auch etwas expliziter sein: [files]verweist auf anfängliche Pattern-Matching-Dateien im aktuellen Verzeichnis, die möglicherweise umbenannt werden sollen (z. B. *stimmt alles überein, aber nur im aktuellen Verzeichnis).
Patrick Dark
Ihr Link verweist auf einen anderen Link rename, der das Format hat rename from to fileund keine regulären Ausdrücke unterstützt. Eigentlich hat meine Linux-Distribution (Cent OS 7) genau diese Version.
Alex Che
6

Wenn sich Dateien in mehreren Verzeichnissen befinden, benennen Sie sie nach einer Suche wie folgt um:

find -iname file_*.png -type f -exec rename -n 's/file_[0-9]{3}(.*\.png)/upl$1/' {} \;

das -n nach dem umbenennen ist zu testen, entfernen um fortzufahren! -)

Auf diese Weise assoziieren Sie das Finden und Umbenennen von Macht.

Persönlich habe ich es verwendet, um den Quell-Header .h in .hpp umzubenennen

find -iname *.h -type f -exec rename 's/(.*\.)h/$1hpp/' {} \;
bcag2
quelle
Es gibt Dokumentation für das -iname, -typeund -execFahnen auf manpages.ubuntu.com/manpages/bionic/man1/find.1.html#expression . ( find --helpIst für diesen Befehl nicht besonders hilfreich.) TL; DR: -inameStimmt nicht mit der Groß- / Kleinschreibung eines Musters überein. -type fstimmt mit "regulären Dateien" überein; und -execführt einen Ausdruck aus, bis er auf ein ;(Semikolon-) Zeichen trifft .
Patrick Dark
5

Dies kann mit wenig Magie der Bash-Parameter-Erweiterung durchgeführt werden!

for f in file_[0-9]*_*; do mv $f upl_${f#file_[0-9]*_}; done

file_[0-9]*_*;- Mit dem ersten Muster werden alle Dateien durchsucht, die mit 'file_anynumber_' beginnen.
${f#file_[0-9]*_}- Mit dem zweiten Muster file_[0-9]*_wird in der Parametererweiterung festgelegt, dass 'file_anynumber_' vom Beginn der Zeichenfolge entfernt werden soll.

Weitere Informationen zu Parameter expansion:

man bash
Basharat Sialvi
quelle
Beachten Sie, dass hier keine regulären Ausdrücke verwendet werden, sondern [0-9]*eine Ziffer gefolgt von einer beliebigen Zeichenfolge. Es gibt wahrscheinlich einen besseren Weg, um nur Zahlen abzugleichen, aber ich kann mir nichts Prägnantes vorstellen.
wjandrea
Wären Sie auch in der Lage, eine Möglichkeit vorzuschlagen, diesen Befehl in allen Unterverzeichnissen rekursiv arbeiten zu lassen?
Francesco DM