Ich habe eine Reihe von Verzeichnissen und Unterverzeichnissen, die Dateien mit Sonderzeichen enthalten, wie diese Datei:
robbie@phil:~$ ls test�sktest.txt
test?sktest.txt
Suchen zeigt eine Escape-Sequenz:
robbie@phil:~$ find test�sktest.txt -ls
424512 4000 -rwxr--r-x 1 robbie robbie 4091743 Jan 26 00:34 test\323sktest.txt
Der einzige Grund, warum ich ihre Namen in die Konsole eingeben kann, ist der Tabulatorabschluss. Dies bedeutet auch, dass ich sie manuell umbenennen kann (und das Sonderzeichen entfernen kann).
Ich habe LC_ALL auf UTF-8 gesetzt, was anscheinend nicht hilft (auch nicht auf einer neuen Shell):
robbie@phil:~$ echo $LC_ALL
en_US.UTF-8
Ich verbinde mich mit ssh von meinem Mac mit dem Computer. Es ist eine Ubuntu-Installation:
robbie@phil:~$ cat /etc/lsb-release
DISTRIB_ID=Ubuntu
DISTRIB_RELEASE=7.10
DISTRIB_CODENAME=gutsy
DISTRIB_DESCRIPTION="Ubuntu 7.10"
Shell ist Bash, TERM ist auf xterm-color gesetzt.
Diese Dateien gibt es schon eine ganze Weile und sie wurden nicht mit dieser Ubuntu-Installation erstellt. Ich weiß also nicht, wie die Einstellungen für die Systemcodierung waren.
Ich habe Dinge ausprobiert wie:
find . -type f -ls | sed 's/[^a-zA-Z0-9]//g'
Aber ich kann keine Lösung finden, die alles kann, was ich will:
- Identifizieren Sie alle Dateien mit nicht darstellbaren Zeichen (die oben genannten ignorieren viel zu viel).
- Führen Sie für alle diese Dateien in einem Verzeichnisbaum (rekursiv) mv oldname newname aus
- Optional besteht die Möglichkeit, Sonderzeichen wie ä in a zu transliterieren (nicht erforderlich, wäre aber genial)
ODER
- Alle diese Dateien korrekt anzeigen (und keine Fehler in Anwendungen, wenn Sie versuchen, sie zu öffnen)
Ich habe Teile und Stücke, wie alle Dateien durchlaufen und verschieben, aber die Dateien zu identifizieren und sie richtig für den Befehl mv zu formatieren, scheint der schwierige Teil zu sein.
Zusätzliche Informationen darüber, warum sie nicht korrekt angezeigt werden oder wie die richtige Codierung "erraten" werden kann, sind ebenfalls willkommen. (Ich habe convmv ausprobiert, aber es scheint nicht genau das zu tun, was ich will: http://j3e.de/linux/convmv/ )
Antworten:
Ich vermute, Sie sehen dieses
�
ungültige Zeichen, weil der Name eine Byte-Sequenz enthält, die nicht für UTF-8 gültig ist. Dateinamen in typischen Unix-Dateisystemen (einschließlich Ihres) sind Byte-Zeichenfolgen, und es liegt an den Anwendungen, zu entscheiden, welche Codierung verwendet wird. Heutzutage gibt es einen Trend zur Verwendung von UTF-8, der jedoch nicht universell ist, insbesondere in Gebieten, die niemals mit einfachem ASCII leben könnten und andere Codierungen verwendet haben, als es UTF-8 noch nicht gab.Versuchen Sie herauszufinden
LC_CTYPE=en_US.iso88591 ls
, ob der Dateiname in ISO-8859-1 (Latin-1) Sinn macht. Wenn dies nicht der Fall ist, versuchen Sie es mit anderen Ländereinstellungen. Beachten Sie, dass hier nur dieLC_CTYPE
Ländereinstellung von Bedeutung ist.In einem UTF-8-Gebietsschema werden mit dem folgenden Befehl alle Dateien angezeigt, deren Name nicht für UTF-8 gültig ist:
Sie können mit recode oder iconv prüfen, ob sie in einem anderen Gebietsschema sinnvoller sind :
Wenn Sie festgestellt haben, dass eine Reihe von Dateinamen in einer bestimmten Codierung enthalten sind (z. B. latin1), können Sie sie auf eine Weise umbenennen
Dies verwendet den Perl- Umbenennungsbefehl , der unter Debian und Ubuntu verfügbar ist. Sie können es übergeben, um
-n
zu zeigen, was es tun würde, ohne die Dateien tatsächlich umzubenennen.quelle
grep [^[:print:]]
nach nicht druckbaren Zeichen suchen. Aber ich habe gerade mit GNU grep getestet und ungültige UTF-8-Sequenzen werden[^[:print:]]
nicht erfasst (was Sinn macht, da sie keine nicht druckbaren Zeichen sind, sondern überhaupt keine Zeichen). Ich habe meinen Beitrag mit einer längeren Grepping-Methode für Zeilen mit ungültigen utf8-Sequenzen bearbeitet. Beachten Sie, dass ich auch die Richtung derrecode
undiconv
Beispiele festgelegt habe.Ich weiß, dass dies eine alte Frage ist, aber ich habe die ganze Nacht nach einer ähnlichen Lösung gesucht. Ich habe ein paar hilfreiche Tipps gefunden, aber sie haben nicht genau das getan, was ich brauchte. Deshalb musste ich ein paar kombinieren, um das richtige Ergebnis zu erzielen
um einfach Sonderzeichen zu entfernen und durch einen (.) Punkt zu ersetzen
zur verwendung in einem cronjob habe ich folgendes gemacht, um jede minute zu rennen
Ich hoffe, jemand findet dies hilfreich, da es meinen Tag gemacht hat :)
quelle
`…`
,$(…)
um dies , dies und das anzuzeigen . (2) Sie sollten immer die Referenzen Ihrer Shell-Variablen angeben (z. B."$f"
), es sei denn, Sie haben einen guten Grund, dies nicht zu tun, und Sie sind sicher, dass Sie wissen, was Sie tun. Dies gilt auch fürecho "$f" | sed …
. Dies gilt auch für den gesamten$(…)
(oder`…`
) Ausdruck. dhmv "$f" "$(echo "$f" | sed "…")"
. … (Fortsetzung)mv
--
"$f" …
-
Wenn Sie nun wissen, welche Codierung für die Dateinamen auf der Remote-Seite verwendet wird ("latin1" - gemäß den Kommentaren zur ersten Antwort), können Sie auch den zweiten Weg gehen - führen Sie ein lokales Terminal aus und ssh in einem solchen Weise, dass die entfernten Dateinamen korrekt angezeigt werden (anstatt auf die erste Weise: Benennen Sie sie um) .
Wie ich könnten Sie ein Terminal lokal starten, das in dieser speziellen Codierung funktioniert, vielleicht so:
LC_ALL = de_DE.latin1 xvt &
xvt
steht für Ihr Terminalprogramm.Vielleicht wird das vorhandene Gebietsschema aufgerufen
en_US.iso88591
und nichten_US.latin1
, wie ich angenommen habe.quelle
Dies entspricht nicht den Massenanforderungen, aber ich hatte gerade ein ähnliches Problem, als ich mehrere Versionen einer Datei mit ähnlichen Namen hatte, die sich nur durch ein seltsames Zeichen unterschieden. Leider bedeutete dies, dass ich die Täter mit dem von mir normalerweise verwendeten Wildcard-Trick nicht umbenennen konnte.
Am Ende habe ich mit Filezilla eine Verbindung als SFTP-Client hergestellt, die Dateien durchsucht und über die GUI umbenannt. Filezilla handhabte die zweifelhaften Zeichen recht gut.
quelle