Listen Sie alle Dateien und Ordner auf, die im Namen ein Fragezeichen (?) Enthalten

487
Valentin Coudert

Beim Kopieren vieler Dateien und Ordner von einem Windows-System auf ein Linux-System ist ein Codierungsproblem aufgetreten. Jetzt sehe ich viele Dateien mit Fragezeichen im Namen.

Ich möchte gerne wissen, wie viele Dateien / Ordner betroffen sind, und ich habe es versucht

find . -type d -o -type f -name '*\?*' 

und

find . -type d -o -type f -name '*?*' 

ohne Glück.

Es listet viele Dateien / Ordner auf, die im Namen kein Fragezeichen enthalten ... (Bitte beachten Sie, dass die Suche rekursiv sein muss)

Hast du eine Lösung?

(Wenn Sie außerdem einen zweiten Befehl haben, um die Anzahl der betroffenen Dateien zu zählen, wäre ich glücklich :))

[edit] Danke für Ihre Antworten, aber das Problem scheint tatsächlich zu sein, dass diese Dateien und Ordner findaufgrund des Kodierungsproblems vom Befehl ausgeschlossen werden. Zunächst scheint es nicht das? Charakter aber eher so etwas wie . Und ich versuche, die Suche an einem anderen Teil ihres Namens durchzuführen, und sie werden immer noch nicht angezeigt (wenn ich sie umbenenne, werde ich das Codierungsproblem los und sie werden wieder sichtbar find).
Dies half mir, sie aufzulisten und zu zählen.

Vielen Dank

0
Der erste Befehl funktioniert für mich. simlev vor 6 Jahren 1
Welche Art von Linux verwenden Sie? Ich habe `find getestet. -name '* \? *' `in Ubuntu 14 und funktionierte gut für mich. Jimmy_A vor 6 Jahren 0
Sie brauchen den `-type d -o -type f` nicht, da` find` standardmäßig sowohl nach Verzeichnissen als auch nach Dateien sucht. Sie können "wc -l" nach "find" für einen Zähler pfeifen Jimmy_A vor 6 Jahren 0
Sie haben eine Lösung in die Frage gestellt. Wenn es Ihr Problem löst, sollten Sie es als Antwort schreiben. Wenn nein, was ist jetzt die eigentliche Frage? Kamil Maciorowski vor 6 Jahren 0
Der Befehl in der verknüpften Antwort: `find. | perl ... `fängt immer noch bei` find` an, aber Sie behaupten, dass die Dateien und Verzeichnisse für `find` unsichtbar sind. Ich schlage vor, Sie beschreiben Ihre Situation besser. Fügen Sie möglicherweise Screenshots hinzu, wenn Sie aufgrund von Zeichensatzproblemen einige Beispieldateinamen nicht kopieren / einfügen können. Außerdem würde ich in Betracht ziehen, eine neue Frage zu stellen, da die von Ihnen gestellten Fragen bereits beantwortet wurden. simlev vor 6 Jahren 0

3 Antworten auf die Frage

1
A.B

Sie haben ein Codierungsproblem, das behoben werden sollte.

Das ?angezeigte by lsist ein Platzhalter und bedeutet nicht, dass die Datei einen Namen hat ?.

So reproduzieren Sie Ihr Problem iconvauf einem üblichen, mit utf8 konfigurierten Linux-System:

$ mkdir /tmp/test $ cd /tmp/test $ touch $(echo é | iconv -t windows-1252) # that's the eacute character $ ls ? $ ls|cat � 

Die letzte Zeile bedeutet nur "ungültige UTF8-Codierung wird angezeigt" und kann wahrscheinlich nicht korrekt kopiert / eingefügt werden, ohne dass die Informationen verloren gehen. windows-1252ist nur ein Beispiel. Es hätte viele andere geben können (zB:) iso-8859-1. Die Informationen sind immer noch da:

$ ls|iconv -f windows-1252 é 

Wenn Sie also herausgefunden haben, welche Kodierung zum Schreiben dieser Dateien unter Linux verwendet wurde (versuchen Sie es iconv -l|egrep -i 'win|iso-8859'mit einer möglichen Kandidatenliste), können Sie versuchen, die Stapelumbenennung durchzuführen. Seien Sie vorsichtig, während ein Beispiel funktionieren könnte, und es kann bei einer anderen Datei fehlschlagen.

Beispiel für die Umbenennung:

ENCODING="windows-1252" # once the right encoding was found for file in *; do dest="$(printf '%s' "$file" | iconv -f "$ENCODING")" mv -i "$file" "$dest.new" mv -i "$dest.new" "$dest" done 
0
simlev

Ihr erster Befehl kann wie folgt geändert werden:

find . -type d -name '*\?*' -o -type f -name '*\?*' 

Auf diese Weise gilt der Filter sowohl für Dateien als auch für Verzeichnisse (ansonsten würden Sie alle Verzeichnisse auflisten und nur Dateien filtern).


Viel einfacher, wie von Jimmy_A in den Kommentaren vorgeschlagen, wäre:

find . -name '*\?*' 

Beachten Sie, dass findstandardmäßig im aktuellen Verzeichnis gesucht wird. Das .kann auch weggelassen werden:

find -name '*\?*' 

Alternativ können Sie die Ergebnisse anzeigen:

find | grep ? 

Um die relevanten Entitäten zu zählen (von Jimmy_A vorgeschlagene Lösung ):

find | grep ? | wc -l 

Befehl, um zu zählen, wie viele Dateien betroffen sind

Um nur Dateien zu zählen, die Sie zu fragen scheinen:

find -type f | grep ? | wc -l 

Testlauf:

?aa a?a aa? aaa $ find | grep ? ./a?a ./?aa ./aa? 

Kommentar:

Ich dachte, ich grepmüsste die -FOption ?buchstäblich behandeln, aber es scheint, dass es ohnehin kein Sonderzeichen ist, es sei denn, der -ESchalter wird verwendet.

 -F, --fixed-strings Interpret PATTERN as a list of fixed strings (instead of regular expressions), separated by newlines, any of which is to be matched.  -E, --extended-regexp Interpret PATTERN as an extended regular expression (ERE, see below). 

Die Frage wurde aktualisiert:

Listen Sie alle Dateien und Ordner auf, deren Namen ein Fragezeichen ( ) enthält

Nicht viel ändert sich: entweder find -name '*�*'oderfind | grep �

Testlauf:

�aa a�a aa� aaa $ find -name '*�*' ./a�a ./�aa ./aa� 

Noch ein Problem:

Wenn Sie Dateien oder Verzeichnisse suchen, die exotische Zeichen enthalten, können Sie die Ergebnisse filtern, indem Sie angeben, welche Zeichen Sie erwarten . Fügen Sie der Liste einfach jedes Zeichen hinzu, das Sie nicht hervorheben möchten:

find | grep -P '[^\w./-_*]' 

Dies ist besonders nützlich, wenn Sie nicht wissen, welcher der problematische Charakter ist. Bitte beachten Sie, dass diese Frage bereits mehrfach auf der Stackexchange gestellt und beantwortet wurde.

0
Attie

find's' -obedeutet " oder ", daher haben Sie möglicherweise ein Problem mit Vorrang ...

Was hast du gemeint

  • -type d oder ( -type f und -name '*\?*' )
    • alle Verzeichnisse
    • alle Dateien mit ?im Namen
  • ( -type d oder -type f ) und -name '*\?*'
    • Nur Verzeichnisse und Dateien mit ?dem Namen

Sie können geschweifte Klammern verwenden. findIhr Befehl lautet also:

find . \( -type d -o -type f \) -name '*\?*' 

Beispiel:

$ touch 'aaa' 'a?a' $ mkdir 'bbb' 'b?b' $ touch 'bbb/ccc' 'bbb/c?c' 
$ find . -type d -o -type f -name '*\?*' . ./bbb ./bbb/c?c ./b?b ./a?a 
$ find . \( -type d -o -type f \) -name '*\?*' ./bbb/c?c ./b?b ./a?a 

Sie können dann die Ausgabe wc -lweiterleiten, um die Anzahl der Zeilen zu zählen:

$ find . \( -type d -o -type f \) -name '*\?*' | wc -l 3 

Andere schlagen vor, dass Sie das entfernen -type d -o -type f. Dies ist eine gute Option, sofern Sie nicht versuchen, andere Typen auszuschließen (z. B. Gerät / Zeichengerät / Symlinks / Pipes / Sockets blockieren).