Es kann zu Problemen kommen, wenn Sie Dateien und Verzeichnisse gleichzeitig umbenennen möchten . Nur eine Datei umzubenennen ist einfach genug. Sie möchten jedoch sicherstellen, dass die Verzeichnisse auch umbenannt werden. Sie können nicht einfach mv Motörhead/Encöding Motorhead/Encoding
da Motorhead
zum Zeitpunkt des Anrufs nicht existieren.
Wir müssen also zuerst alle Dateien und Ordner gründlich durchlaufen und dann nur die aktuelle Datei oder den aktuellen Ordner umbenennen. Das Folgende funktioniert mit GNU find
und Bash 4.2.42 auf meinem OS X.
#!/usr/bin/env bash
find "$1" -depth -print0 | while IFS= read -r -d '' file; do
d="$( dirname "$file" )"
f="$( basename "$file" )"
new="${f//[^a-zA-Z0-9\/\._\-]/}"
if [ "$f" != "$new" ] # if equal, name is already clean, so leave alone
then
if [ -e "$d/$new" ]
then
echo "Notice: \"$new\" and \"$f\" both exist in "$d":"
ls -ld "$d/$new" "$d/$f"
else
echo mv "$file" "$d/$new" # remove "echo" to actually rename things
fi
fi
done
Sie können den regulären Ausdruck ändern, indem Sie verwenden, new="${f//[\\\/\:\*\?\"<>|]/}"
wenn Sie alles ersetzen möchten, was Windows nicht verarbeiten kann.
Speichern Sie dieses Skript als rename.sh
, und machen Sie es mit ausführbar chmod +x rename.sh
. Dann nenne es wie rename.sh /some/path
.
Stellen Sie sicher, dass Kollisionen von Dateinamen (" Notice
" Ansagen) behoben werden.
Wenn Sie absolut sicher sind, dass es die richtigen Ersetzungen vornimmt, entfernen Sie das Symbol echo
aus dem Skript , um die Objekte tatsächlich umzubenennen, anstatt nur zu drucken, was es tut.
Aus Sicherheitsgründen würde ich empfehlen, dies zunächst an einer kleinen Teilmenge von Dateien zu testen.
Optionen erklärt
Um zu erklären, was hier vor sich geht:
-depth
wird sicherstellen, dass Verzeichnisse mit der Tiefe zuerst rekursiv behandelt werden, damit wir alles vom Ende an "zusammenfassen" können. Normalerweise find
wird anders überquert (aber nicht in der Breite zuerst).
-print0
Stellt sicher, dass die find
Ausgabe durch Nullen getrennt ist, damit wir sie read -d ''
in die file
Variable einlesen können . Auf diese Weise können wir mit allen Arten von seltsamen Dateinamen umgehen, auch mit Leerzeichen und sogar mit Zeilenumbrüchen.
- Wir werden das Verzeichnis der Datei mit bekommen
dirname
. Vergessen Sie nicht, Ihre Variablen immer korrekt in Anführungszeichen zu setzen, da sonst ein Pfad mit Leerzeichen oder glühenden Zeichen dieses Skript beschädigen würde.
- Wir erhalten den tatsächlichen Dateinamen (oder Verzeichnisnamen) mit
basename
.
- Anschließend entfernen wir alle ungültigen Zeichen aus der
$f
Verwendung von Bashs Funktionen zum Ersetzen von Zeichenfolgen. Ungültig bedeutet, dass es sich nicht um einen Klein- oder Großbuchstaben, eine Ziffer, einen Schrägstrich ( \/
), einen Punkt ( \.
), einen Unterstrich oder einen Minus-Bindestrich handelt.
- Wenn
$f
es bereits sauber ist (der gereinigte Name ist identisch mit dem aktuellen Namen), überspringen Sie ihn.
- Wenn
$new
das Verzeichnis bereits vorhanden ist $d
(z. B. Sie haben Dateien mit dem Namen resume
und résumé
im selben Verzeichnis), geben Sie eine Warnung aus. Sie möchten es nicht umbenennen, da dies auf einigen Systemen mv foo foo
zu Problemen führt. Andernfalls,
- Wir benennen die ursprüngliche Datei (oder das ursprüngliche Verzeichnis) schließlich in ihren neuen Namen um
Da dies nur auf die tiefste Hierarchie angewendet wird, erfolgt die Umbenennung Motörhead/Encöding
in Motorhead/Encoding
in zwei Schritten:
mv Motörhead/Encöding Motörhead/Encoding
mv Motörhead Motorhead
Dadurch wird sichergestellt, dass alle Ersetzungen in der richtigen Reihenfolge erfolgen.
Beispieldateien und Testlauf
Nehmen wir an, einige Dateien in einem Basisordner mit dem Namen test
:
test
test/Motörhead
test/Motörhead/anöther_file.mp3
test/Motörhead/Encöding
test/Randöm
test/Täst
test/Täst/Töst
test/with space
test/with-hyphen.txt
test/work
test/work/resume
test/work/résumé
test/work/schedule
Hier ist die Ausgabe eines Laufs im Debug-Modus (mit dem echo
vor dem mv
), dh die Befehle, die aufgerufen werden würden, und die Kollisionswarnungen:
mv test/Motörhead/anöther_file.mp3 test/Motörhead/another_file.mp3
mv test/Motörhead/Encöding test/Motörhead/Encoding
mv test/Motörhead test/Motorhead
mv test/Randöm test/Random
mv test/Täst/Töst test/Täst/Tost
mv test/Täst test/Tast
mv test/with space test/withspace
Notice: "resume" and "résumé" both exist in test/work:
-rw-r—r-- … … test/work/resume
-rw-r—r-- … … test/work/résumé
Beachten Sie die Abwesenheit von Nachrichten für with-hyphen.txt
, schedule
und test
selbst.
mv
bereits vorhanden ist. Dies kann passieren (1), wenn Sie Dateien haben, die bereits bereinigt sind (was zu führtmv foo foo
), oder (2), wenn Sie Dateien mit dem gleichen Namen außer haben für die Sonderzeichen (zBmv Encöding Encoding
wo SieEncoding
zusätzlich zuEncöding
).Ich weiß, dass es nicht genau das ist, was Sie wollten, aber wenn Sie die ursprüngliche Codierung kennen, können Sie möglicherweise
convmv
die Codierung in UTF-8 ändern, was die meisten Probleme beheben sollte.Dies funktionierte für mich in einem Ordner mit einigen ungültig codierten polnischen Dateinamen:
Beachten Sie, dass dieser Befehl nichts umbenennt.
--notest
Option hinzufügen , um die Dateien wirklich umzubenennen.quelle
convmv
Option erstaunlich einfach und perfekt. Bei OP mit einer potenziellen Vielzahl von Zeichensätzen könnte dies mit der anderen Antwort zusammengeführt werden, daconvmv
offenbar bekannt ist, wann es das richtige Format aufweist oder wann es nicht. Durch Durchlaufen der Zeichensätze überconvmv --list
würde man sie richtig codieren.convmv -t utf8 --nfc -f iso-8859-1 --notest -r .
- Das--nfc
war vor OS X Linux-konform zu sein oder so, durch einfaches Eingebenconvmv
werden die (nützlichen) Optionen aufgegeben.Ich weiß, Sie haben nach dem Umbenennen gefragt.
Mit Software wie MusicBrainz Picard können Sie dem Problem jedoch ganz einfach ausweichen .
Es ist in der Lage, Musik zu identifizieren (Audio-Fingerabdruck), alle erforderlichen Daten (einschließlich Titelbilder, sofern verfügbar) aus der riesigen MusicBrainz- Datenbank herunterzuladen und die Dateien so zu verschieben, dass Ihre Sammlung zu jedem beliebigen Muster passt. Ich benutze es seit Jahren und es funktionierte immer perfekt mit allem von Kyrillisch bis Arabisch; und natürlich (zumindest für lateinische Skripte) kann es auch die Konvertierung nach ASCII durchführen.
Bei diesem Ansatz spielt es keine Rolle, wie unordentlich / schlecht Ihre Sammlung wirklich benannt ist, solange die Dateien lesbar und vollständig sind.
(Habe ich schon erwähnt, dass es kostenlos ist? Sowohl in der Redefreiheit als auch im Freibier? Sowohl in der Software als auch in der Datenbank ..?)
quelle