GNU/Linux >> LINUX-Kenntnisse >  >> Linux

Wie kann man Dateien mit ungültiger Codierung massenhaft umbenennen oder ungültig codierte Zeichen massenweise ersetzen?

Ich weiß, dass es nicht genau das ist, was Sie wollten, aber wenn Sie die ursprüngliche Codierung kennen, können Sie vielleicht convmv verwenden um die Kodierung auf UTF-8 zu ändern, was die meisten Probleme beheben sollte.

Dies hat bei mir bei einem Ordner mit einigen ungültig codierten polnischen Dateinamen funktioniert:

convmv -f cp1250 -t utf8 -r .

Beachten Sie, dass dieser Befehl eigentlich nichts umbenennt; --notest hinzufügen Möglichkeit, die Dateien wirklich umzubenennen.


Sie werden einige Probleme bekommen, wenn Sie Dateien und umbenennen wollen Verzeichnisse gleichzeitig. Nur eine Datei umzubenennen ist einfach genug. Aber Sie möchten sicherstellen, dass die Verzeichnisse auch umbenannt werden. Sie können nicht einfach mv Motörhead/Encöding Motorhead/Encoding seit Motorhead wird zum Zeitpunkt des Aufrufs nicht existieren.

Wir müssen also zuerst alle Dateien und Ordner mit der Tiefe durchlaufen und dann nur die aktuelle Datei oder den aktuellen Ordner umbenennen. Folgendes 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 Regex ändern, indem Sie new="${f//[\\\/\:\*\?\"<>|]/}" verwenden wenn Sie etwas ersetzen möchten, was Windows nicht verarbeiten kann.

Speichern Sie dieses Skript unter rename.sh , machen Sie es mit chmod +x rename.sh ausführbar . Nennen Sie es dann wie rename.sh /some/path .

Stellen Sie sicher, dass Dateinamenkonflikte behoben werden („Notice ” Ankündigungen).

Wenn Sie sich absolut sicher sind es die richtigen Ersetzungen vornimmt, entfernen Sie den echo aus dem Skript, um Dinge tatsächlich umzubenennen, anstatt nur zu drucken, was es tut.

Sicherheitshalber würde ich empfehlen, dies zuerst an einer kleinen Teilmenge von Dateien zu testen.

Optionen erklärt

Um zu erklären, was hier vor sich geht:

  • -depth stellt sicher, dass Verzeichnisse mit der Tiefe zuerst rekursiv sind, sodass wir alles vom Ende "aufrollen" können. Normalerweise find geht anders (aber nicht in der Breite zuerst).
  • -print0 sorgt für den find Die Ausgabe ist durch Null getrennt, sodass wir sie mit read -d '' lesen können in file Variable. Das hilft uns, mit allen Arten von seltsamen Dateinamen umzugehen, einschließlich solchen mit Leerzeichen und sogar Zeilenumbrüchen.
  • Wir bekommen das Verzeichnis der Datei mit dirname . Vergessen Sie nicht, Ihre Variablen immer richtig in Anführungszeichen zu setzen, sonst würde jeder Pfad mit Leerzeichen oder Globbing-Zeichen dieses Skript beschädigen.
  • Wir erhalten den tatsächlichen Dateinamen (oder Verzeichnisnamen) mit basename .
  • Dann entfernen wir alle ungültigen Zeichen aus $f Verwenden der String-Ersetzungsfunktionen von Bash. Ungültig bedeutet alles, was kein Klein- oder Großbuchstabe, eine Ziffer, ein Schrägstrich (\/ ), ein Punkt (\. ), ein Unterstrich oder ein Minus-Bindestrich.
  • Falls $f bereits sauber ist (der bereinigte Name ist identisch mit dem aktuellen Namen), überspringe ihn.
  • Falls $new existiert bereits im Verzeichnis $d (Beispiel:Sie haben Dateien mit dem Namen resume und résumé im selben Verzeichnis), eine Warnung ausgeben. Sie möchten es nicht umbenennen, da auf einigen Systemen mv foo foo verursacht ein Problem. Ansonsten
  • Wir benennen schließlich die ursprüngliche Datei (oder das Verzeichnis) in ihren neuen Namen um

Da dies nur auf die tiefste Hierarchie wirkt, wird Motörhead/Encöding umbenannt bis Motorhead/Encoding erfolgt in 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 durchgeführt werden.

Beispieldateien und Testlauf

Nehmen wir an, einige Dateien befinden sich in einem Basisordner namens 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 einer Ausführung im Debug-Modus (mit dem echo vor der mv ), d. h. die Befehle, die aufgerufen 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 das Fehlen von Nachrichten für with-hyphen.txt , schedule , und test selbst.


Linux
  1. So benennen Sie Dateien unter Linux um

  2. So entpacken Sie Dateien unter Linux (mit Beispielen)

  3. Wie benenne ich mehrere Dateien mit Find um?

  4. Wie benenne ich den Satz von Dateien mit Muster um?

  5. Wie kann man Zeichen rekursiv durch sed ersetzen?

So benennen Sie eine Datei (en) in Linux um

So synchronisieren Sie Dateien mit Unison unter Linux

So entfernen Sie Dateien mit einer bestimmten Erweiterung in Linux

So finden Sie Dateien mit dem fd-Befehl in Linux

So laden Sie Dateien mit FileZilla hoch

Wie benenne ich alle Dateien mit Sonderzeichen und Leerzeichen in einem Verzeichnis um?