Ich muss fremde Dateien finden und identifizieren (von ungefähr 900K-Dateien auf einem 2T-Laufwerk). Es gibt viele Dateien, die ich behalten möchte, und ich habe Dateinamenmuster für diese bekannten guten Dateien. Ich möchte die Dateien finden, die zu keinem der Muster passen.
Wie finde ich Dateien, die nicht mit einer Liste von Dateinamenmustern übereinstimmen?
Ich kann find
eine Liste aller Dateien abrufen und grep -v
für das Ergebnis eine Liste der in einer Datei gespeicherten Muster verwenden. Ist dies die kanonische Methode oder haben Sie eine präzise Möglichkeit, diese nicht konformen Dateien zu finden?
Klarstellung - basierend auf den Antworten finden Sie hier einige weitere Informationen. Ich erwarte zahlreiche Muster (> 20, vielleicht> 100), möchte sie in einer Datei speichern und möchte auf jeden Fall auf einfache Weise neue hinzufügen. Ich würde es vorziehen, eine große Liste von Suchparametern (fragil) nicht direkt zu bearbeiten, aber das Erstellen dieser Liste könnte funktionieren.
Antworten:
Da Sie Perl erwähnen ...
Rufen Sie dies als auf
Ersetzen Sie das
.
am Ende durch die Spitze des Baumes, den Sie gehen möchten.quelle
find(1)
ist mächtig genug, um das zu tun, was Sie brauchen. Sammeln Sie einfach alle konformen Namen in Klammern in einem Ausdruck und negieren Sie ihn, um nicht konforme Dateinamen anzuzeigen. Zum Beispiel, um alle Dateien anzuzeigen, die nicht benannt*.txt
sind*.bz2
, oder*.zip
:Sie können
-not
anstelle von\!
GNU und BSD verwendenfind
. Es ist nicht POSIX-kompatibel, erfordert jedoch kein Escape, um zu verhindern, dass die Shell es interpretiert.Um den Ausdruck aus Mustern in einer Datei zu erstellen, ist es eine kleine Sache der Shell-Skripterstellung:
Dies erwartet eine Datei im aktuellen Verzeichnis, die
.fnpatterns
mit einem Muster pro Zeile aufgerufen wird. Um den obigen Einzeiler nachzuahmen, müsste er Folgendes enthalten:Beachten Sie, dass das Shell-Skript die
*
Zeichen in den Mustern für Sie maskiert.Sie können dies beliebig komplex machen. Einige Ideen:
In
-type f
mit demfind
Befehl , so dass es nur normale Dateien zeigt, keine Verzeichnisse.Übergeben Sie den Namen der Musterdatei als Argument, anstatt ihn an einem festen Ort zu erwarten
Behalten Sie die Musterdatei bei, wo sie sich befindet, aber fügen Sie
-o -name .fnpatterns
sie dem erstelltenfind
Befehl hinzu, damit sie nicht in der Ausgabe angezeigt wird. (Dies würde auch die Notwendigkeit vermeiden, dass dershift
Hack die Führung-o
im aufgebauten Ausdruck "frisst" .)Fügen Sie dem
find
Befehl über-exec
oder ähnliches Aktionen hinzu .Lassen Sie leere Zeilen oder Kommentare in der Musterdatei zu
quelle
set --
bedeuten?$1
,$2
usw. Die zweite Appends-o $pattern
der Parameterliste, so dass wir alle am Ende der Schleife haben die Muster aus der.fnpatterns
Datei , als ob an das Skript in quasi übergeben -find
Ausdrucksform. Wir haben ein Extra-o
auf der Vorderseite, also schalten wirshift
es aus und wickeln das Ganze mit dem drittenset --
Befehl in eine Negation . Jetzt enthält unsere Positionsparameterliste einen gültigenfind
Ausdruck, den wir mit übergeben"$@"
.