Batch-Umbenennung von Dateien

151

Ich habe ein Verzeichnis voller Bilder:

image0001.png
image0002.png
image0003.png
...

Und ich möchte, dass ein Einzeiler sie in (etwa) umbenennt.

0001.png
0002.png
0003.png
...

Wie mache ich das?

Internet-Mann
quelle
8
Dies ist eine der häufigsten FAQs zu Unix-Befehlen. Ich kann sie auf dieser Site nicht finden. Sollten wir dieses Community-Wiki erstellen?
Gilles
5
Ich verstehe nicht warum. Es ist eine spezifische Frage mit einer überprüfbaren Antwort.
Internet Mann
3
Wenn Sie X thunar -B *.pngausführen, wird es nicht viel einfacher als mit dem Massenumbenennungs-GUI-Tool von Thunar.
Dotjoe
@dotjoe Danke, Thunar ist in der Tat interessant.
Volker Siegel

Antworten:

106

Wenn Sie Bash oder eine andere POSIX-kompatible Shell verwenden:

for f in *.png; do
    mv -- "$f" "${f#image}"
done
W_Whalley
quelle
2
Dies ist eine der Methoden zum Ersetzen von Parametern, die im Advanced Bash-Scripting-Handbuch von Mendel Coopers ( tldp.org/LDP/abs/html
W_Whalley,
2
@W_Whalley Ich empfehle dringend , diesen Leitfaden zugunsten des Wooledge Bash-Leitfadens zu meiden .
Wildcard
@Wildcard: Aus welchen Gründen empfehlen Sie, den ABS-Leitfaden zu vermeiden?
Christian Severin
@ChristianSeverin Werbung für schlechte Praktiken und völlig fehlerhaften Code. Überprüfen Sie die Links auf meiner Profilseite.
Wildcard
Wenn Sie nicht wissen, wie Sie dieses Beispiel für verschiedene Dateimuster anpassen können, sollten Sie sich den Abschnitt zur Parametererweiterung des oben genannten Handbuchs ansehen .
Lex82
108

Auf Debian und Derivaten arbeitet Perl renameähnlich sedwie folgt:

  rename -v 's/image//' *.png

Es gibt auch die renamedavon util-linux, die wie folgt funktioniert, stattdessen:

  rename image '' *.png
Internet-Mann
quelle
6
Sie sollten wirklich erklären, dass dies ein Perl-Programm ist, das möglicherweise installiert werden muss, und dass es reguläre Ausdrücke als Argument verwendet.
Ah, das war mir nicht bewusst. Ich werde die kanonische Antwort würdigen, wenn ich sie identifiziere :)
Internet-Mann
5
Dieses renameProgramm stammt aus einer Perl-Beispieldistribution. Debian und Ubuntu liefern es als /usr/bin/rename. Andere Unix-Varianten bieten möglicherweise keine oder eine völlig andere /usr/bin/rename.
Gilles
1
Einige Versionen von renametake a from to -Ersetzungsmuster:rename [options] <expression> <replacement> <file>...
meldet sich
1
Wenn Sie ein Debian-basiertes System verwenden und sudo apt-get install umbenennt, können Sie den Befehl rename verwenden. Es ist für Dateinamen ausgelegt.
Strg-Alt-Delor
41

zmv

Die zsh-Shell verfügt über einen leistungsstarken Befehl zum Batch-Umbenennen zmv.

Zuerst müssen Sie den zmvBefehl wie folgt aktivieren (dies kann in Ihren gehen ~/.zshrc).

autoload zmv

Die grundlegende Syntax lautet zmv PATTERN REPLACEMENT. Das Muster ist ein Shell-Glob-Ausdruck. Teile des Musters können von Klammern umgeben sein. Der Ersetzungstext kann usw. enthalten $1, $2um auf die N-te Gruppe in Klammern im Muster zu verweisen. Zum Beispiel:

zmv 'image(*.png)' '$1'

Sie können zsh auch auffordern, automatisch zu definieren $1, $2usw., damit die Platzhalterzeichen im Muster übereinstimmen:

zmv -w 'image*.png' '$1.png'
Gilles
quelle
4
sweeeeeeeeeeeeeeeet. Noch ein Grund, warum ich zsh lernen sollte.
ixtmixilix
1
@ixtmixilix was gibt es zu lernen? Beginnen Sie einfach damit und fügen Sie vielleicht prezto ( github.com/sorin-ionescu/prezto ) hinzu, um etwas mehr Attraktivität zu erzielen.
Gerry
Wirklich cool, wie in zmv's man gezeigt, kann dies weiter vereinfacht werden, indem man den Alias ​​mmv = 'noglob zmv -W' zu: mmv * .c.orig orig / *
.c
Aktivieren zmvprezto erfordert uncommenting die Zeile in Ihrer ~ / .zpreztorc folgenden # Set the Zsh functions to load (man zshcontrib).gebenzstyle ':prezto:load' zfunction 'zargs' 'zmv'
33

Normalerweise benutze ich das nette und einfache Hilfsprogramm mmv ( man page ) für diesen Verwendungszweck:

$ mmv "image*.png" "#1.png"

wird Ihre Aufgabe ausführen.

Das #1in dem Zielmuster wird durch das ersetzt, was mit dem Platzhalter in dem Quellmuster übereinstimmt. Dies funktioniert auch für mehrere Platzhalter und kann zum Beispiel verwendet werden, um die Reihenfolge von Teilen von Dateinamen zu ändern. Sie können auch einfach kompliziertere Dinge tun, z. B. Kleinbuchstaben in Großbuchstaben umwandeln.

Stellen Sie sicher, dass Sie die Muster vor der Shell schützen, indem Sie sie in Anführungszeichen setzen.

Marcel Stimberg
quelle
Vielen Dank, dass Sie auf dieses Dienstprogramm hingewiesen haben. Ich habe es in Debian-, Ubuntu- und Cygwin-Repositories gefunden. Ich hatte Probleme mit der Manpage, fand jedoch einige Webseiten und diese Stapelüberlauf-Frage, mit deren Hilfe erklärt wurde, wie Sie sie verwendeten. stackoverflow.com/questions/417916/how-to-do-a-mass-rename
W_Whalley
Vielen Dank, ich habe der Antwort weitere Informationen hinzugefügt, um sie verständlicher zu machen.
Marcel Stimberg
3
Kann es nicht genug unterstützen! Es ist so einfach und freundlich. Verfügbar für OS X in Homebrew.
Greg Dubicki
9

POSIX sh für Schleife

Verwendet sed zum Umbenennen

for i in image*jpg
do 
  mv -v "$i" "$(echo "$i" | sed -e 's/^\.\/image//' - )"
done
X Tian
quelle
6

Ich mag Perl so:

perl -nlE '$old=$_; s/image//; qx(mv $old $_)'

Sie können dasselbe Muster auch für andere Aufgaben wie das Kopieren der Dateien in ein anderes Verzeichnis verwenden:

perl -nlE '$old=$_; s(image)(/path/to/new/dir/); qx(mv $old $_)'
gvkv
quelle
2
Oder (sicherer!):rename($old,$_)
Reinierpost
5

qmv

Der Befehl qmvvon renameutilsöffnet einen Editor mit einer Liste von Dateinamen mit zwei Spalten, die durch einen Tabulator getrennt sind. Jede Zeile enthält einen Dateinamen, der in beiden Spalten identisch ist. Die rechte Spalte zeigt die neuen Namen der Dateien.
Um Änderungen vorzunehmen, bearbeiten Sie die Namen auf der rechten Seite. In diesem Beispiel ist der :%s/...visuelle Blockmodus hilfreich.

Dateinamen in Ihrem Editor

$ qmv *.png

Im Editor:

image0001.png           image0001.png
image0002.png           image0002.png
image0003.png           image0003.png         
~                                             
~                                             
~                                             
~                                             
"/tmp/user/1000/qmvxWyVMs" 3L, 93C

Bearbeiten Sie die Namen in der rechten Spalte:
(Entfernen des imagePräfixes aus allen Zeilen im visuellen Blockmodus)

image0001.png           0001.png
image0002.png           0002.png
image0003.png           0003.png         
~                                             
~                                             
~                                             
~                                             
:wq

Umbenennungsprotokoll:

image0001.png -> 0001.png
image0002.png -> 0002.png
image0003.png -> 0003.png

(zB Ubuntu: apt-get install renameutils)

Volker Siegel
quelle
3

rekursiv

Einfaches erneutes Auswählen von image * png-Dateien, ohne dass Zeilenumbrüche in den Dateinamen erforderlich sind

find . -name "image*.png" | while read f; do mv -v "$f" "$(echo "$f" | sed -e 's/^\.\/image//' - )"; done

Sicher, kann mit Leerzeichen, neuen Zeilen, Backslashes und allem anderen umgehen :

find . -name "image*.png" | while IFS= read -r f; do 
   mv -v "$f" "$(echo "$f" | sed -e 's/^\.\/image//' - )"; 
done
X Tian
quelle
1

POSIX sh mit einer while-Schleife

Namen aus dem findBefehl lesen.

find . -maxdepth 1 -type f -name 'image*png' | while IFS= read -r f; do
  mv -v "$f" "$(echo "$f" | sed -e 's/^\.\/image//' - )"
done

Namen aus einer Datei lesen

while IFS= read -r f; do mv -v "$f" "$(echo "$f"|sed -e 's/^\.\/image//' - )"; done < flist
X Tian
quelle
1

Verwenden der Shell-Klammererweiterung :

for N in {0001..1000}; do mv "{image,}$N.png"; done
αғsнιη
quelle
1

Für Windows und Linux ist dieses Perl-Skript ausreichend. in diesem Fall:

$ rnm -l 's/^image//' '*.png'

Das Skript kann unter Verzeichnissen rekursiv ausgeführt werden und allen sogar eine Zählung voranstellen:

$ rnm -r 's/^/$counter./' '/\.png$/'

UTF-8-Zeichen werden sowohl unter Windows als auch unter Linux korrekt behandelt.

circulosmeos
quelle
0

Sie können dieses Tool verwenden: rnm ( Webseite )

Für Ihren Fall wäre der Befehl:

rnm -rs '/^image//' *.png

Weitere Beispiele / Dokumente finden Sie hier .

Jahid
quelle
0

Probieren Sie brename ( https://github.com/shenwei356/brename ), ein praktisches plattformübergreifendes Befehlszeilentool zum sicheren Batch-Umbenennen von Dateien / Verzeichnissen über reguläre Ausdrücke (unterstützt Windows, Linux und OS X).

@patrickDurusau sagte:

Linux bietet eine Vielzahl von Optionen zum Umbenennen von Batch-Dateien, aber ich habe keine Mängel im Namen festgestellt, die mir aufgefallen sind.

Eigenschaften:

  • Plattformübergreifend . Unterstützt Windows, Mac OS X und Linux.
  • Sicher . Durch Überprüfung möglicher Konflikte und Fehler .
  • Dateifilterung . Unterstützt das Ein- und Ausschließen von Dateien über reguläre Ausdrücke. Keine Notwendigkeit, Befehle wie auszuführen find ./ -name "*.html" -exec CMD.
  • Submatch mit entsprechendem Wert über Schlüsselwertdatei umbenennen .
  • Umbenennung über aufsteigende Ganzzahl .
  • Rekursives Umbenennen von Dateien und Verzeichnissen .
  • Trockenlauf unterstützen .
  • Bunte Ausgabe .

Befehl:

$ brename -f .png -p image
[INFO] checking: [ ok ] 'image0001.png' -> '0001.png'
[INFO] checking: [ ok ] 'image0002.png' -> '0002.png'
[INFO] checking: [ ok ] 'image0003.png' -> '0003.png'
[INFO] 3 path(s) to be renamed
[INFO] renamed: 'image0001.png' -> '0001.png'
[INFO] renamed: 'image0002.png' -> '0002.png'
[INFO] renamed: 'image0003.png' -> '0003.png'
[INFO] 3 path(s) renamed
Wei Shen
quelle
-5

ls * png | während read -rf; do f2 = "` echo $ f | sed -e's / image // '`"; mv $ f $ f2; getan

Ivan P
quelle
Irgendwas stimmt nicht: "mv: fehlender Zieldatei-Operand nach 'image0001.png'"
Internet-Mann
3
Es gibt viele Probleme mit Ihrem Code. Das Parsen der Ausgabe von lsfordert nur Ärger. readsollte sein read -r. Alle Variablensubstitutionen sollten in doppelten Anführungszeichen stehen.
Gilles
Sie könnten dies effektiver schreiben als for f in *png; do f2="$(echo "$f" | sed -e 's/image//')"; mv "$f" "$f2"; done. Das Parsen lsist weder notwendig noch eine gute Idee .
Kojiro