finden und löschen von Dateien mit nicht-ascii-Namen
Habe ich einige alte migriert Dateien, die nicht druckbare Zeichen enthalten. Ich möchte alle Dateien finden, die mit solchen Namen, und löschen Sie Sie vollständig aus dem system.
Beispiel:
ls -l
-rwxrwxr-x 1 cws cws 0 Dec 28 2011 ??"??
ls -lb
-rwxrwxr-x 1 cws cws 0 Dec 28 2011 \a\211"\206\351
Ich möchte alle diese Dateien.
Hier ein Beispiel screenshot von dem, was ich sehe, wenn ich eine ls
in diesen Ordner:
Möchte ich diese Dateien mit nicht druckbaren Zeichen und löschen Sie Sie.
InformationsquelleAutor Rohit Chopra | 2013-10-02
Du musst angemeldet sein, um einen Kommentar abzugeben.
Nicht-ASCII-Zeichen
ASCII-Zeichencodes reichen von
0x00
zu0x7F
im hex. Daher, jedes Zeichen mit einem code größer als0x7F
ist ein nicht-ASCII-Zeichen. Dies umfasst den Großteil der Zeichen, die in UTF-8 (ASCII-codes sind im wesentlichen eine Teilmenge von UTF-8). Zum Beispiel, das japanische Zeichenist in hex codiert in UTF-8 als
UTF-8 wurde die Standard-Zeichenkodierung auf, unter anderem, Red Hat Linux ab version 8.0 (2002), SuSE Linux ab version 9.1 (2004), und Ubuntu-Linux seit der version 5.04 (2005).
ASCII-steuerzeichen
Aus der ASCII-codes,
0x00
durch0x1F
und0x7F
darstellen steuerzeichen wieESC
(0x1B
). Diese steuerzeichen wurden ursprünglich nicht beabsichtigt gedruckt werden, obwohl einige von Ihnen, wie das Zeilenvorschub-Zeichen0x0A
können interpretiert und dargestellt werden.Auf meinem system
ls
zeigt alle control-Zeichen als?
standardmäßig, es sei denn, ich gehe in den--show-control-chars
option. Ich vermute, dass die Dateien, die Sie löschen möchten, enthalten ASCII-steuerzeichen, im Gegensatz zu nicht-ASCII-Zeichen. Dies ist eine wichtige Unterscheidung: wenn Sie löschen, Dateinamen mit nicht-ASCII-Zeichen können Sie wegblasen die legitime Dateien, die nur zufällig mit dem Namen in eine andere Sprache.Reguläre Ausdrücke für die Zeichen-codes
POSIX
POSIX bietet eine sehr praktische Sammlung von Charakter-Klassen für den Umgang mit diesen Arten von Zeichen (Dank bashophil für den Hinweis):
PCRE
Perl-Kompatible Reguläre Ausdrücke ermöglichen hexadezimalen Zeichencodes verwenden Sie die syntax
Beispielsweise eine PCRE-regex für das japanische Zeichen
あ
wäreZusätzlich zu den POSIX-character-Klassen, die oben aufgeführt sind, PCRE bietet auch die
[:ascii:]
Charakter-Klasse, die eine praktische Abkürzung für[\x00-\x7F]
.GNU-version von
grep
unterstützt PCRE mit der-P
Flagge, aber BSDgrep
(auf Mac OS X, zum Beispiel) nicht. Weder GNU noch BSDfind
unterstützt PCRE regexes.Finden die Dateien
GNU
find
unterstützt die POSIX regexes (Dank iscfrc für den Hinweis auf die Reinefind
Lösung zur Vermeidung von Laich-zusätzliche Prozesse). Der folgende Befehl listet alle Dateinamen (aber nicht in directory-Namen) unter dem aktuellen Verzeichnis, die enthalten nicht-druckbare steuerzeichen:Regex ist ein wenig kompliziert, weil die
-regex
option hat, um die gesamte Datei Weg, nicht nur den Dateinamen, und da gehe ich davon aus, dass wir nicht wollen Weg zu Blasen Dateien mit dem normalen Namen einfach, weil Sie in Verzeichnissen mit Namen, die mit control-Zeichen.Löschen der entsprechenden Dateien, übergeben Sie einfach die
-delete
optionfind
, , nachdem alle anderen Optionen (dies ist entscheidend; eine Weitergabe-delete
als erste option wird wegblasen alles, was in Ihrem aktuellen Verzeichnis):Ich hoch empfehlen, läuft der Befehl ohne die
-delete
ersten, so dass Sie sehen können, was gelöscht werden, bevor es zu spät ist.Wenn Sie auch passieren die
-print
- option können Sie sehen, was gelöscht wird, wie der Befehl ausgeführt wird:Wegblasen alle Pfade (Dateien oder Verzeichnisse) enthalten steuerzeichen, die regex können vereinfacht werden, und Sie können die drop -
-type
option:Dieser Befehl, wenn Sie einen Verzeichnisnamen enthält steuerzeichen, auch wenn keiner von den Dateinamen innerhalb des Verzeichnisses zu tun, werden Sie alle gelöscht werden.
Update: Suche nach nicht-ASCII - und steuerzeichen
Sieht es aus wie deine Dateien enthalten nicht-ASCII-Zeichen und ASCII-steuerzeichen. Wie es sich herausstellt,
[:ascii:]
ist nicht eine POSIX-Zeichenklasse, aber es ist zur Verfügung gestellt von PCRE. Ich konnte Sie nicht finden, eine POSIX-regex zu tun, so ist es Perl ist die Rettung. Wir werden weiterhinfind
zu durchqueren unser Verzeichnis, aber wir übergeben die Ergebnisse an Perl für die Verarbeitung.Sicherstellen, dass wir verarbeiten kann Dateinamen mit Zeilenumbrüchen (das scheint wahrscheinlich, dass in diesem Fall), brauchen wir das
-print0
argumentfind
(unterstützt sowohl GNU-und BSD-Versionen); diese trennt die Datensätze mit einem null-Zeichen (0x00
) statt einem Zeilenumbruch, da das null-Zeichen ist der einzige Charakter, der kann nicht in einen gültigen Dateinamen unter Linux. Wir übergeben zu müssen, die entsprechende Flagge-0
zu unserer Perl-code, so dass es weiß, wie es Datensätze voneinander getrennt sind. Der folgende Befehl print, dass jeder Pfad, im aktuellen Verzeichnis rekursiv:Beachten Sie, dass dieser Befehl nur Ausgeburten einer einzigen Instanz des Perl-interpreters, das ist gut für die Leistung. Der Start-Pfad-argument (in diesem Fall
.
fürCWD
) ist optional in GNUfind
aber ist erforderlich, BSDfind
auf Mac OS X, so habe ich es aus Gründen der Portabilität.Nun für unsere regex. Hier ist eine PCRE-regex-matching-Namen, die enthalten nicht-ASCII-oder nicht-druckbare (d.h. Kontroll -) Zeichen (oder beides):
Den folgenden Befehl druckt alle Pfade (Verzeichnisse oder - Dateien) im aktuellen Verzeichnis, die mit dieser regex:
Den
chomp
ist notwendig, weil es streift die abschließenden null-Zeichen von jedem Weg, der würde sonst passen unsere regex. Löschen Sie die entsprechenden Dateien und Verzeichnisse, wir können die folgenden:Diese auch ausdrucken, was wird gelöscht, wenn der Befehl ausgeführt wird (obwohl steuerzeichen interpretiert werden, so wird die Ausgabe nicht ganz die Leistung von
ls
).[:print:]
oder[:graph:]
finden Sie unter faqs.org/docs/abs/HTML/regexp.htmlVielen Dank, aktualisiert meine Antwort.
Du bist herzlich willkommen. Ich wollte konstruieren eine Antwort, die mich aber du warst schneller 🙂 ich mag die Verwendung von execdir.
Vielen Dank für die informative Antwort. Wenn ich versuche [^[:ascii:]], bekomme ich finden: Invalid character class name". Jede Idee, was könnte die Ursache?
Ich habe versucht, die Vorschläge in dieser Antwort, aber leider ist Sie nicht in der Lage gewesen zu verfolgen, die Dateien mit der nicht-druckbare Zeichen in Ihrem Namen. Ich habe gerade aktualisiert meine Frage um einen screenshot, wenn das wird helfen, jemand zwicken 🙂
InformationsquelleAutor ThisSuitIsBlackNot
Nun werden Sie wohl gelöst haben deine Frage, aber es funktionierte nicht gut für meinen Fall, ich hatte Dateien, die wurde nicht gezeigt
find
wenn ich-regex
wechseln. So entwickelte ich diese Problemumgehung mithilfels
. Hoffe, es kann nützlich sein, um jemanden.Im Grunde, was für mich gearbeitet wurde:
Bricht es in Teile:
Diese wird rekursiv (
-R
) Liste (ls
) Dateien im aktuellen Verzeichnis, eine Datei pro Zeile (-1
), indem Sie jede Datei, indem seine inode-Nummer (-i
). Ergebnisse werden angrep
.Filter jeden Eintrag, wenn man bedenkt, jede Eingabe als text (
-a
), auch wenn es schließlich mit binären.grep
lassen, eine Linie passieren, wenn es ein Zeichen enthält verschiedene, von den in der Liste angegebenen. Ergebnisse werden anwhile
.Diese
while
wird eine Iteration durch alle Einträge, extrahieren Sie die inode-Nummer und die übergabe der inode zufind
wird, das dann die Datei löschen.InformationsquelleAutor Alexandre Schmidt
Könnten Sie drucken nur die Zeilen mit einem backslash mit grep:
InformationsquelleAutor dave12345678
Ist es möglich, PCRE mit grep -P, nur nicht mit finden (leider). Sie können Kette finden mit grep die Verwendung von exec. Mit PCRE (perl regex), können wir die ascii-Klasse und finden keinen char, der nicht-ascii-Zeichen.
Den folgenden exec nicht ausführen, es sei denn, der erste gibt einen nicht-Fehler-code. In diesem Fall bedeutet der Ausdruck entsprach dem Namen. Ich benutzte sh -c da -exec nicht wie die Rohre.
InformationsquelleAutor Dan
Basierend auf dieser Antwort, versuchen:
oder:
Anmerkung: Nach Dateien gedruckt werden, die richtig, entfernen Sie die
#
Charakter.Siehe auch: Wie kann ich grep für alle nicht-ASCII-Zeichen.
InformationsquelleAutor kenorb