Wie kann ich Dateien mit ungültiger Kodierung in Massen umbenennen oder ungültige kodierte Zeichen durch Massen ersetzen?

20056
Afri

Ich habe einen Debian-Server und hoste Musik für einen Internetradiosender. Ich habe Probleme mit Dateinamen und Pfaden, da viele Dateien eine ungültige Kodierung erhalten haben, zum Beispiel:

./music/Bändname - Some Title - additional Info/B�ndname - 07 - This Title Is Cörtain, The EncÃding Not.mp3 

Im Idealfall möchte ich alles entfernen, was nicht aus Buchstaben A-Z/ a-zZahlen 0-9oder Bindestrich -/ Unterstrich besteht _. Das Ergebnis sollte in etwa so aussehen:

./music/Bndname-SomeTitle-additionalInfo/Bndname-07-ThisTitleIsCrtain,TheEncdingNot.mp3 

Wie kann man dies für eine Reihe von Dateien und Verzeichnissen erreichen?

Ich habe diese ähnliche Frage gesehen: Massenumbenennen (oder korrekte Anzeige) von Dateien mit Sonderzeichen

Dies fixiert jedoch nur die Kodierung. Ich würde einen strengeren Ansatz bevorzugen, wie oben beschrieben.

13

3 Antworten auf die Frage

14
mik01aj

Ich weiß, dass es nicht genau das ist, was Sie wollten, aber wenn Sie die ursprüngliche Kodierung kennen, können Sie die Kodierung möglicherweise convmvin UTF-8 ändern, was die meisten Probleme beheben sollte.

Dies funktionierte für mich in einem Ordner mit ungültigen kodierten polnischen Dateinamen:

convmv -f cp1250 -t utf8 -r . 

Beachten Sie, dass dieser Befehl nichts umbenennt. --notestOption hinzufügen, um die Dateien wirklich umzubenennen.

Für diejenigen, die einen statischen Satz haben (oder keine abwechslungsreiche Mischung von Zeichensätzen haben), ist die Option "convmv" erstaunlich einfach und perfekt. Für OP mit einer potenziellen Vielzahl von Zeichensätzen könnte dies mit der anderen Antwort zusammengeführt werden, da "convmv" zu wissen scheint, wann es oder nicht das richtige Format gefunden wird. Durch das Durchlaufen der Zeichensätze über 'convmv --list' würde man sie richtig kodieren lassen. vor 10 Jahren 1
Damit meine ich, wenn man als OP einen Debian-Server betreibt, würde man heutzutage sicherlich von UTF8 ausgehen. In diesem Fall kann man die ursprünglichen Buchstaben behalten. Ich hatte den a-Ordner einiger nordischer Zeichen und benutzte: `convmv -t utf8 --nfc -f iso-8859-1 --notest -r .` - Der` --nfc` sollte Linux vor OS entsprechen X oder so, wenn Sie einfach "convmv" eingeben, werden die (nützlichen) Optionen aufgegeben. vor 10 Jahren 1
13
slhck

Sie werden einige Probleme haben, wenn Sie Dateien und Verzeichnisse gleichzeitig umbenennen möchten . Das Umbenennen einer Datei 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/Encodingda Motorheadzum Zeitpunkt des Anrufs nicht existieren.

Wir müssen also zunächst alle Dateien und Ordner tief durchqueren und dann nur die aktuelle Datei oder den aktuellen Ordner umbenennen. Folgendes funktioniert mit GNU findund Bash 4.2.42 unter 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="$" 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 Regex ändern, indem Sie verwenden, new="$"wenn Sie etwas ersetzen möchten, das Windows nicht verarbeiten kann.

Speichern Sie dieses Skript als rename.sh, machen Sie es mit ausführbar chmod +x rename.sh. Dann nennen Sie es gerne rename.sh /some/path.

Stellen Sie sicher, dass eventuelle Dateinamenskollisionen ( NoticeAnsagen) aufgelöst werden.

Wenn Sie absolut sicher sind, dass die richtigen Ersetzungen vorgenommen werden, entfernen Sie die Option echoaus dem Skript, um die Dinge tatsächlich umzubenennen, anstatt nur das zu drucken, was sie tut.

Um sicherzugehen, würde ich empfehlen, dies zunächst an einer kleinen Untermenge von Dateien zu testen.


Optionen erklärt

Um zu erklären, was hier vorgeht:

  • -depthDadurch wird sichergestellt, dass Verzeichnisse zuerst tief rekonstruiert werden, sodass wir alles vom Ende her aufrollen können. Normalerweise finddurchquert er anders (aber nicht zuerst die Breite).
  • -print0stellt sicher, dass die findAusgabe mit Nullen begrenzt ist, sodass wir sie read -d ''in die fileVariable einlesen können . Auf diese Weise können wir mit allen Arten von seltsamen Dateinamen umgehen, einschließlich solchen mit Leerzeichen und sogar Zeilenumbrüchen.
  • Wir erhalten das Verzeichnis der Datei mit dirname. Vergessen Sie nicht, Ihre Variablen immer korrekt zu zitieren. Andernfalls würde jeder Pfad mit Leerzeichen oder Globing-Zeichen dieses Skript beschädigen.
  • Wir erhalten den tatsächlichen Dateinamen (oder Verzeichnisnamen) mit basename.
  • Dann entfernen wir alle ungültigen Zeichen aus den $fBash-Funktionen zum Ersetzen von Zeichenketten. 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 $fbereits sauber ist (der bereinigte Name ist mit dem aktuellen Namen identisch), überspringen Sie ihn.
  • Wenn $newbereits ein Verzeichnis vorhanden ist $d(z. B. wenn Sie Dateien benannt haben resumeund sich résuméin demselben Verzeichnis befinden), geben Sie eine Warnung aus. Sie möchten es nicht umbenennen, da es auf einigen Systemen mv foo foozu Problemen führt. Andernfalls,
  • Schließlich benennen wir die ursprüngliche Datei (oder das ursprüngliche Verzeichnis) in ihren neuen Namen um

Da dies nur für die tiefste Hierarchie gilt, erfolgt die Umbenennung Motörhead/Encödingin Motorhead/Encodingin zwei Schritten:

  1. mv Motörhead/Encöding Motörhead/Encoding
  2. mv Motörhead Motorhead

Dadurch wird sichergestellt, dass alle Ersetzungen in der richtigen Reihenfolge ausgeführt werden.


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 echodavor 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, scheduleund testselbst.

Möglicherweise möchten Sie eine Logik hinzufügen, um den Fall zu behandeln, in dem das Ziel des `mv 'bereits vorhanden ist. Dies kann passieren (1), wenn Sie bereits Dateien haben, die bereits bereinigt sind (was zu' mv foo foo 'führt) oder (2) if Sie haben Dateien mit demselben Namen, mit Ausnahme der Sonderzeichen (z. B. "mv Encöding Encoding", wo Sie zusätzlich zu "Encöding" auch eine "Encoding" -Datei haben). Scott vor 11 Jahren 1
Gute Idee, danke. Gibt es konkrete Vorschläge, was in diesem Fall zu tun ist? Zugegeben - dies auf saubere und gesunde Weise zu erreichen, ist schwieriger als es auf den ersten Blick scheint. Wenn Sie etwas haben, können Sie es selbstverständlich bearbeiten. slhck vor 11 Jahren 0
Ich glaube nicht, dass es sinnvoll ist, über den automatischen Umgang mit den Kollisionen nachzudenken - identifizieren Sie sie einfach für den Benutzer und lassen Sie ihn von ihm handeln. Ich habe Ihre Antwort bearbeitet, wie Sie vorgeschlagen haben. Scott vor 11 Jahren 0
+1 für die Verwendung des Beispiels mit "Encöding" Zu viel fön! :-) Marcel vor 10 Jahren 0
Nach drei Jahren komme ich immer noch hierher zurück. so nützlich! :-) Afri vor 8 Jahren 0
Ich habe dieses Skript verwendet, aber den Regex in `new =" $ " "Geändert, so dass nur ungültige Windows-Zeichen entfernt und gültig bleiben Leerzeichen, kaufmännische Und-Zeichen, Kommas usw. Sehr nützlich, danke! Jeremiah Rose vor 5 Jahren 0
0
Alois Mahdal

Ich weiß, du hast nach dem Umbenennen gefragt.

Mit Software wie MusicBrainz Picard können Sie dem Problem jedoch ganz leicht ausweichen .

Es ist in der Lage, Musik zu identifizieren (Audio-Fingerprinting), alle erforderlichen Daten (einschließlich Titelbilder, sofern verfügbar) aus der großen MusicBrainz- Datenbank herunterzuladen und die Dateien so zu verschieben, dass Ihre Sammlung in jedes beliebige Muster passt. Ich benutze es seit Jahren und es hat immer perfekt mit kyrillisch bis arabisch zusammengearbeitet; und natürlich (zumindest für lateinische Skripte) kann es auch in ASCII konvertiert werden.

Bei diesem Ansatz spielt es keine Rolle, wie unordentlich / schlecht benannt Ihre Sammlung ist, solange die Dateien lesbar und vollständig sind.

(Habe ich schon erwähnt, dass es kostenlos ist? Sowohl in freier Rede als auch in Freibier? Sowohl in der Software als auch in der Datenbank ..?)