4 Stimmen

Linux Suche nach mehreren Mustern

Ich muss ungefähr 1500 Dateinamen finden und frage mich, ob es eine Möglichkeit gibt, gleichzeitig mehrere Suchbefehle auszuführen.

Derzeit mache ich etwas wie

für fil in $(cat my_file)
do
  find . -name $fil >> outputfile
done

Gibt es eine Möglichkeit, mehrere Instanzen von find zu starten, um den Vorgang zu beschleunigen? Derzeit dauert es etwa 7 Stunden, um diese Schleife nacheinander auszuführen ein Datei nach der anderen.

3voto

Angesichts der von Ihnen erwähnten 7-stündigen Laufzeit gehe ich davon aus, dass das Dateisystem einige Millionen Dateien enthält, sodass die im Betriebssystempuffer geladenen OS-Daten bei einer Abfrage wiederverwendet werden, bevor die nächste Abfrage beginnt. Sie können diese Hypothese testen, indem Sie dieselbe find-Abfrage einige Male timen, wie im folgenden Beispiel.

tini ~ > time find . -name IMG_0772.JPG -ls
25430459 9504 lrwxrwxrwx   1 omg omg  9732338 Aug  1 01:33 ./pix/rainbow/IMG_0772.JPG
20341373 5024 -rwxr-xr-x   1 omg omg  5144339 Apr 22  2009 ./pc/2009-04/IMG_0772.JPG
22678808 2848 -rwxr-xr-x   1 omg omg  2916237 Jul 21 21:03 ./pc/2012-07/IMG_0772.JPG

real    0m15.823s
user    0m0.908s
sys 0m1.608s

tini ~ > time find . -name IMG_0772.JPG -ls
25430459 9504 lrwxrwxrwx   1 omg omg  9732338 Aug  1 01:33 ./pix/rainbow/IMG_0772.JPG
20341373 5024 -rwxr-xr-x   1 omg omg  5144339 Apr 22  2009 ./pc/2009-04/IMG_0772.JPG
22678808 2848 -rwxr-xr-x   1 omg omg  2916237 Jul 21 21:03 ./pc/2012-07/IMG_0772.JPG

real    0m0.715s
user    0m0.340s
sys 0m0.368s

Im Beispiel wurde der zweite find viel schneller ausgeführt, weil das Betriebssystem immer noch Speicher pufferspeichern von dem ersten find hatte. [Auf meinem kleinen Linux 3.2.0-32 System sind laut top im Moment 2,5 GB RAM Puffer, 0,3 GB sind frei und 3,8 GB in Benutzung (d. h. etwa 1,3 GB für Programme und OS).]

Wie auch immer, um die Verarbeitung zu beschleunigen, müssen Sie einen Weg finden, den OS-Datenspeicher besser zu nutzen. Beispielsweise können Sie Ihren Systemspeicher verdoppeln oder vervierfachen. Als Alternative probieren Sie den locate-Befehl aus. Die Abfrage
time locate IMG_0772.JPG
dauert konsistent weniger als eine Sekunde auf meinem System. Sie möchten vielleicht updatedb kurz vor Beginn der Aufgabe ausführen, die die 1500 Dateinamen findet. Siehe man updatedb. Wenn das Verzeichnis . in Ihrem find's nur einen kleinen Teil des gesamten Dateisystems angibt, sodass die locate-Datenbank zahlreiche irrelevante Dateien enthält, verwenden Sie verschiedene prune-Optionen, wenn Sie updatedb ausführen, um die Größe der locate-Datenbank zu minimieren, die beim Ausführen von locate aufgerufen wird; und danach führen Sie ein einfaches updatedb aus, um andere Dateinamen in der locate-Datenbank wiederherzustellen. Durch die Verwendung von locate können Sie die Laufzeit wahrscheinlich auf 20 Minuten verkürzen.

2voto

F. Hauri Punkte 57640

Vielleicht so etwas wie

find . \( -name file1 -o -name file2 -o ... \) >outputfile

Sie könnten Zeilen dieser Art erstellen, abhängig von der Anzahl der Namen in my_file:

find . \( $(xargs outputfile

2voto

Hai Vu Punkte 33787

Diese Lösung ruft find und fgrep nur einmal auf:

find . | fgrep -f my_file > outputfile

Ich gehe davon aus, dass my_file eine Liste der Dateien enthält, nach denen Sie suchen, wobei jeder Name in einer separaten Zeile steht.

Erklärung

  1. Der Befehl find findet alle Dateien (einschließlich Verzeichnisse) im aktuellen Verzeichnis. Die Ausgabe ist eine Liste von Dateien/Verzeichnissen, jeweils eine pro Zeile
  2. Der Befehl fgrep sucht in der Ausgabe des find-Befehls, gibt aber anstatt des Suchbegriffs in der Befehlszeile die Suchbegriffe aus my_file an --das ist die Funktion des -f Flags.
  3. Die Ausgabe des fgrep-Befehls, die Liste der gesuchten Dateien, wird in die Datei outputfile umgeleitet

1voto

Gibt es eine Möglichkeit, mehrere Instanzen von Find zu spawnen, um den Prozess zu beschleunigen.

Das ist nicht der richtige Weg, das Problem zu lösen, da find durch I/O und Dateisystem begrenzt ist.

Verwenden Sie entweder mehrere -name Argumente, die zusammen mit -o gruppiert sind, um ein find Befehl zu benutzen, um gleichzeitig nach mehreren Dateinamen zu suchen, oder finden Sie alle Dateien einmal und verwenden Sie ein Tool wie grep, um die resultierende Liste von Dateien nach den gewünschten Dateinamen zu durchsuchen.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X