Massenumbenennung, * nix-Version

4833
Paolo B.

Ich habe nach einer Möglichkeit gesucht, eine große Anzahl von gleichnamigen Dateien umzubenennen, ähnlich wie diese (eine Windows-bezogene Frage), außer dass ich * nix (Ubuntu und FreeBSD, separat) verwende. Um nur zusammenzufassen, während Sie die Shell verwenden (Bash, CSH usw.), benenne ich eine Reihe von Dateien in Massen um, z. B. die folgenden Dateien:

Beethoven - Pelz Elise.mp3
Beethoven - Mondscheinsonate.mp3
Beethoven - Ode an die Freude.mp3
Beethoven - Wut über die verlorene Penny.mp3

wird wie diese umbenannt?

Fur Elise.mp3
Moonlight Sonata.mp3
Ode an Joy.mp3
Wut über den verlorenen Penny.mp3

Der Grund, warum ich dies tun möchte, ist, dass diese Sammlung von Dateien unter einem Verzeichnis namens "Beethoven" (dh dem Präfix der Dateinamen) abgelegt wird, und dass diese Informationen über den Dateinamen selbst überflüssig sind.

11

9 Antworten auf die Frage

12

Das Umbenennungsprogramm wird das tun, was Sie möchten.

Benutz einfach rename 's/Beethoven\ -\ //g' *.mp3

Können Sie bitte bearbeiten, um einen Link zum Dienstprogramm bereitzustellen, oder ist es Standard in beiden genannten Distributionen (Ubuntu und FreeBSD)? Chris W. Rea vor 14 Jahren 0
Es kommt mit Perl. Debian verwendet es als Umbenennungsbefehl, daher vermute ich, dass Ubuntu dies auch tut. Es gibt noch einen weiteren Umbenennungsbefehl, der wertlos ist. Überprüfen Sie die Manpage. derobert vor 14 Jahren 1
wow, die umbenannte Syntax sieht vim als Ersatz sehr ähnlich aus: D nXqd vor 12 Jahren 0
Der Port in / usr / ports / sysutils / rename hat in FreeBSD einwandfrei funktioniert Josh W. vor 12 Jahren 0
10
jtimberman

Wie so viele Dinge mit Linux / Unix gibt es mehrere Möglichkeiten, dies zu tun!

Einige verwenden möglicherweise mmv (Masse mv).

Der Befehl zum Umbenennen oder Vor- namen, der mit einigen Perl-Paketen (neuere Ubuntu und Debian) geliefert wird, kann dies ebenfalls tun.

prename 's/Beethoven\ -\ //g' Beethoven*.mp3 

Beachten Sie, dass das Umbenennungstool auf Fedora 10 nicht das gleiche Programm wie dieses ist und anders funktioniert. Es ist Teil eines anderen Pakets, util-linux-ng und kann hier gefunden werden .

Ich gehe oft nur in die Shell, um aus der Gewohnheit herauszukommen (schließlich gab es solche Werkzeuge nicht immer).

mkdir -p Beethoven for x in Beethoven\ -\ * do mv "$x" Beethoven/"$" done 

Dadurch wird das Beethoven-Verzeichnis erstellt und die Datei in dieses Verzeichnis / Dateiname verschoben, wobei für das Dateiname "Beethoven -" durch nichts ersetzt wird.

Als Test vorher:

$ ls Beethoven - Fur Elise.mp3 Beethoven - Ode to Joy.mp3 Beethoven - Moonlight Sonata.mp3 Beethoven - Rage Over the Lost Penny.mp3 

Nach dem:

$ ls Beethoven/ Fur Elise.mp3 Ode to Joy.mp3 Moonlight Sonata.mp3 Rage Over the Lost Penny.mp3 
4
nagul

Versuchen Sie diese Lösung, die mit einer Kombination aus grep und umbenannt wurde. Es wird davon ausgegangen, dass Sie eine ganze Reihe von Verzeichnissen haben, die Sie umbenennen müssen. Wenn es nur wenige gibt, würde ich mit dem manuellen Ansatz gehen, wobei das "Artist" -Muster für jeden fest codiert ist.

# Rename any mp3 files in the directory hierarchy of type "a - b.mp3" to "b.mp3" find . -name "*.mp3" -exec rename -n -v 's|^(.*/).*-\s*(.*)\s*$|$1$2|g' {} \; 

Erklärung von find :
Der Befehl find findet alle Dateien mit der Erweiterung .mp3 in der aktuellen Dateihierarchie und ruft das jeweils an -exec übergebene Argument auf . Beachten Sie, dass innerhalb -exec, {} bezieht sich auf das Argument übergeben Fund (Dateipfad + Name). Die \;Sorgt für die ;übergeben wird, um zu umbenennen und stattdessen das Ende des von Anzeigen finden Befehl.

Der oben gegebene Befehl hat den Schalter -n (keine Aktion); Daher wird Ihnen nur mitgeteilt, was passieren würde, wenn Sie es ausführen würden. Ich empfehle, diesen Befehl ohne die Option -n auszuführen, nachdem Sie ihn einmal ausgeführt haben und mit den vorgeschlagenen Ergebnissen zufrieden sind.

Nun zum Regex.

  • ^ entspricht dem Anfang der Zeichenfolge.
  • $ stimmt mit dem Ende der Zeichenfolge überein.
  • . passt zu jedem Zeichen
  • *bedeutet null oder mehr des vorhergehenden Konstrukts. .*bedeutet zB null oder mehr Zeichen.
  • \s steht für ein beliebiges Leerzeichen.
  • \S steht für ein beliebiges Zeichen ohne Leerzeichen.
  • Alles, was in ()wird aufgefangen und reflektiert wird, wie $1, $2je nach seiner Position.

Der reguläre Ausdruck:

  • Sucht am Anfang nach einer optionalen Verzeichnisstruktur, erfasst diese in $ 1: (.*/)
  • Überspringt alles bis zum " -":.*-
  • Erfasst den Rest der Zeichenfolge mit Ausnahme von führenden und nachgestellten Leerzeichen in $ 2: (.*)
  • Schreibt die Datei als $ 1 $ 2 um. Dies sollte "/path/to/file/""filename.mp3" sein.

Hier ist mein Testlauf:

/tmp/test$ ls -R .: a b c z-unknown.mp3  ./a: a3.mp3 a - longer title3.mp3 c.mp3 disc2 a - longer title2.mp3 a - long title.mp3 disc 1 the band - the title.mp3  ./a/disc 1: a - title1.mp3 a - title2.mp3  ./a/disc2: a - title1.mp3 a - title2.mp3  ./b: cd - ab - title3.mp3 cd - title1.mp3 cd - title2.mp3 c.mp3  ./c: c-pony2.mp4 c - pony3.mp3 c - pony4.mp3 c-pony.mp3  /tmp/test$ find . -name "*.mp3" -exec rename -v 's|^(.*/).*-\s*(.*)\s*$|$1$2|g' {} \; ./c/c-pony.mp3 renamed as ./c/pony.mp3 ./c/c - pony4.mp3 renamed as ./c/pony4.mp3 ./c/c - pony3.mp3 renamed as ./c/pony3.mp3 ./z-unknown.mp3 renamed as ./unknown.mp3 ./a/the band - the title.mp3 renamed as ./a/the title.mp3 ./a/a - longer title2.mp3 renamed as ./a/longer title2.mp3 ./a/a - longer title3.mp3 renamed as ./a/longer title3.mp3 ./a/disc 1/a - title1.mp3 renamed as ./a/disc 1/title1.mp3 ./a/disc 1/a - title2.mp3 renamed as ./a/disc 1/title2.mp3 ./a/a - long title.mp3 renamed as ./a/long title.mp3 ./a/disc2/a - title1.mp3 renamed as ./a/disc2/title1.mp3 ./a/disc2/a - title2.mp3 renamed as ./a/disc2/title2.mp3 ./b/cd - title1.mp3 renamed as ./b/title1.mp3 ./b/cd - title2.mp3 renamed as ./b/title2.mp3 ./b/cd - ab - title3.mp3 renamed as ./b/title3.mp3  /tmp/test$ ls -R .: a b c unknown.mp3  ./a: a3.mp3 c.mp3 disc 1 disc2 longer title2.mp3 longer title3.mp3 long title.mp3 the title.mp3  ./a/disc 1: title1.mp3 title2.mp3  ./a/disc2: title1.mp3 title2.mp3  ./b: c.mp3 title1.mp3 title2.mp3 title3.mp3  ./c: c-pony2.mp4 pony3.mp3 pony4.mp3 pony.mp3 

Regexp ist eine knifflige Angelegenheit, und ich habe schon viele Fehler gemacht, als ich sie geschrieben habe. Daher würde ich mich sehr über den Mangel an Verdienst freuen. Ich weiß, dass ich einige Tests gefunden habe.

1
Zach Scrivena

Ich habe ein Befehlszeilen-Java-Programm zusammengestellt, das das Umbenennen von Dateien (und Verzeichnissen) zu einem Kinderspiel macht, insbesondere für das Scripting. Es ist kostenlos und Open Source, sodass Sie es nach Herzenslust anpassen können:

RenameWand
http://renamewand.sourceforge.net/

Einige relevante Anwendungsbeispiele:

Verschieben Sie Dateien des Formulars "<a> - <b>"in das entsprechende Verzeichnis "<a>":

java -jar RenameWand.jar "<a> - <b>" "<a>/<b>" 

Sortieren Sie die Dateien nach dem Zeitpunkt der letzten Änderung und benennen Sie sie mit einer dreistelligen Nummer um:

java -jar RenameWand.jar "<a>" "<3|#FT> <a>" 

Teile des Dateinamens neu anordnen und Groß- / Kleinschreibung ändern:

java -jar RenameWand.jar "<album> - <artist> - <song>.<ext>"  "<artist.upper> <album.title> - <song>.<ext.lower>" 
1
ocodo

zmv Das zsh-Umbenennungstool ist sehr gut.

# zmv "programmable rename" # Replace spaces in filenames with a underline zmv '* *' '$f:gs/ /_' # Change the suffix from *.sh to *.pl zmv -W '*.sh' '*.pl' # lowercase/uppercase all files/directories $ zmv '(*)' '${(L)1}' # lowercase $ zmv '(*)' '${(U)1}' # uppercase 

Weitere Hinweise hier ...

0
TechScott

Für Pinguinköpfe ist dies leicht in einem Shell-Skript oder AWK-Skript möglich. Für uns Sterbliche möchten Sie vielleicht den Midnight Commander ausprobieren. Bei den meisten Linux-Distributionen gibt es eine Shell-Eingabeaufforderung mc -a. Sie können Dateien mit regulären Ausdrücken umbenennen. Ich habe den Artikel bei GeekStuff http://www.thegeekstuff.com/2009/06/how-to-rename-files-in-group/ verwendet, um mir zu helfen.

0
Peter Eisentraut

Verwenden Sie vidir und verwenden Sie dann die Editorfunktionen, um das Umbenennungsmuster anzuwenden.

NAME

vidir - Verzeichnis bearbeiten

ZUSAMMENFASSUNG

vidir [--verbose] [verzeichnis | datei | -] ...

BESCHREIBUNG

Mit vidir können Sie den Inhalt eines Verzeichnisses in einem Texteditor bearbeiten. Wenn kein Verzeichnis angegeben ist, wird das aktuelle Verzeichnis bearbeitet.

Beim Bearbeiten eines Verzeichnisses wird jedes Element im Verzeichnis in einer eigenen nummerierten Zeile angezeigt. Mit diesen Zahlen verfolgt vidir, welche Elemente geändert werden. Löschen Sie Zeilen, um Dateien aus dem Verzeichnis zu entfernen, oder bearbeiten Sie Dateinamen, um Dateien umzubenennen. Sie können auch Zahlenpaare wechseln, um Dateinamen auszutauschen.

Wenn "-" als zu bearbeitendes Verzeichnis angegeben ist, liest es eine Liste der Dateinamen von stdin und zeigt diese zur Bearbeitung an. Alternativ kann eine Liste von Dateien in der Befehlszeile angegeben werden.

BEISPIELE

vidir vidir * .jpeg Typische Anwendungen.

finden | vidir - Bearbeiten Sie auch den Inhalt des Unterverzeichnisses. Um Unterverzeichnisse zu löschen, löschen Sie ihren gesamten Inhalt und das Unterverzeichnis selbst im Editor.

find -type f | vidir - Bearbeiten Sie alle Dateien unter dem aktuellen Verzeichnis und den Unterverzeichnissen.

AUTOR

Joey Hess 2006-2010

Modifikationen von Magnus Woldrich 2011

URHEBERRECHTE ©

Copyright 2006-2011 der vidir "AUTHOR" wie oben aufgeführt.

Lizenziert unter der GNU GPL.

0
William Jockusch

Hier ist ein einfaches Befehlszeilenbeispiel. Ich hatte das Wort "white" in der Mitte der Namen einer Reihe von PNG-Dateien. Ich wollte es herausnehmen und nur einen einzigen Unterstrich hinterlassen. Das hat den Trick:

for i in *.png; do mv "$i" "$"; done 
0
ocodo

Auf einem * nix ohne perl renameverfügbar

Auf einigen * nix-Versionen ist keine Umbenennung verfügbar, daher muss die Umbenennung mithilfe einer anderen Methode erfolgen. Vor ein paar Jahren habe ich zmvhier vorgeschlagen, was zwar großartig ist, aber nicht unbedingt verfügbar ist.

Durch die Verwendung von "builtins" und "sed" können wir schnell ein Shell-Skript erstellen, um dies zu tun, was uns eine sehr ähnliche Syntax wie das Perl-Umbenennungsskript gibt, während einige Fehler beim Umgang mit Fehlern fehlen, wird die Arbeit erledigt.

sedrename() { if [ $# -gt 1 ]; then sed_pattern=$1 shift for file in $(ls $@); do mv -v "$file" "$(sed $sed_pattern <<< $file)" done else echo "usage: $0 sed_pattern files..." fi } 

Verwendungszweck

sedrename 's/Beethoven\ -\ //g' *.mp3  before:  ./Beethoven - Fur Elise.mp3 ./Beethoven - Moonlight Sonata.mp3 ./Beethoven - Ode to Joy.mp3 ./Beethoven - Rage Over the Lost Penny.mp3  after:  ./Fur Elise.mp3 ./Moonlight Sonata.mp3 ./Ode to Joy.mp3 ./Rage Over the Lost Penny.mp3 

Angenommen, wir wollten auch Zielordner erstellen ...

Da mvkeine Ordner erstellt werden, die wir hier nicht verwenden sedrenamekönnen, ist dies eine ziemlich kleine Änderung. Ich denke, es wäre schön, es auch einzubeziehen.

Wir benötigen eine Utility-Funktion abspath(oder einen absoluten Pfad), damit wir die Zielordner für ein Sed / Rename-Muster generieren können, das eine neue Ordnerstruktur enthält.

abspath () { case "$1" in /*)printf "%s\n" "$1";; *)printf "%s\n" "$PWD/$1";; esac; } 

Dadurch wird sichergestellt, dass wir die Namen unserer Zielordner kennen. Wenn wir umbenennen, müssen wir es für den Namen der Zieldatei verwenden.

# generate the rename target target="$(sed $sed_pattern <<< $file)"  # Use absolute path of the rename target to make target folder structure mkdir -p "$(dirname $(abspath $target))"  # finally move the file to the target name/folders mv -v "$file" "$target" 

Hier ist das vollständige Ordner-fähige Skript ...

sedrename() { if [ $# -gt 1 ]; then sed_pattern=$1 shift for file in $(ls $@); do target="$(sed $sed_pattern <<< $file)" mkdir -p "$(dirname $(abspath $target))" mv -v "$file" "$target" done else echo "usage: $0 sed_pattern files..." fi } 

Natürlich funktioniert es auch dann, wenn wir keine speziellen Zielordner haben.

Wenn wir alle Songs in einen Ordner legen wollten, können ./Beethoven/wir Folgendes tun:

Verwendungszweck

sedrename 's|Beethoven - |Beethoven/|g' *.mp3  before:  ./Beethoven - Fur Elise.mp3 ./Beethoven - Moonlight Sonata.mp3 ./Beethoven - Ode to Joy.mp3 ./Beethoven - Rage Over the Lost Penny.mp3  after:  ./Beethoven/Fur Elise.mp3 ./Beethoven/Moonlight Sonata.mp3 ./Beethoven/Ode to Joy.mp3 ./Beethoven/Rage Over the Lost Penny.mp3 

Bonusrunde ...

Verwenden Sie dieses Skript, um Dateien aus Ordnern in einen einzelnen Ordner zu verschieben:

Angenommen, wir wollten alle übereinstimmenden Dateien zusammenstellen und im aktuellen Ordner ablegen, können wir dies tun:

sedrename 's|.*/||' **/*.mp3  before:  ./Beethoven/Fur Elise.mp3 ./Beethoven/Moonlight Sonata.mp3 ./Beethoven/Ode to Joy.mp3 ./Beethoven/Rage Over the Lost Penny.mp3  after:  ./Beethoven/ # (now empty) ./Fur Elise.mp3 ./Moonlight Sonata.mp3 ./Ode to Joy.mp3 ./Rage Over the Lost Penny.mp3 

Beachten Sie die Sed-Regex-Muster

In diesem Skript gelten reguläre Sed-Musterregeln. Diese Muster sind keine PCRE (Perl-kompatiblen regulären Ausdrücke). Sie könnten die erweiterte Syntax für reguläre Ausdrücke gesetzt haben, entweder mit sed -roder sed -E abhängig von Ihrer Plattform.

man re_formatEine vollständige Beschreibung der grundlegenden und erweiterten Regex-Muster finden Sie in der POSIX-Kompatibilität .