2012-04-11 10 views
3

Ich habe eine einfache Suche Befehl, die durch Millionen von Dateien auf einem Server gehen müssen und einige mit einem gegebenen Suffix zu finden. Die Dateien werden im Laufe der Zeit sehr häufig geschrieben und gelöscht. Ich frage mich nur, ob es einen Weg gibt, um schneller zu finden. Die Verwendung von locate kommt nicht in Frage, da eine Datenbank für das Lokalisieren sehr teuer ist.schnelle Shell finden

find /myDirWithThausandsofDirectories/ -name *.suffix 

Auf einigen Servern dauert dieser Befehl Tage!

Irgendwelche Gedanken?

Danke,

+0

Das ist alles, was Sie tun können. find wird die Verzeichnisse für Sie durchlaufen, aber das Durchlaufen 'großer' Verzeichnisse auf einem Unix-System ist natürlich langsam, weil die Verzeichniseinträge gespeichert sind. –

+0

das Problem auflösen? 'finde /myDirWith../dira* -name * .suf & finde /myDirWith../dirb* -name * .suf .... &' Schau auch 'gnu-parallel' oder' xargs -n' Gut Glück! – shellter

+1

Vielleicht ist es gut, etwas anderes zu haben als Millionen von Dateien, z. GDBM-Datenbank oder "relationale" Datenbanken wie MySQL oder PostGresQL, oder noSQL Dinge wie mangodb. –

Antwort

2

Sie das Audit-Subsystem verwenden können, das Erstellen und Löschen von Dateien zu überwachen. Wenn Sie dies mit einem ersten Lauf von find kombinieren, sollten Sie eine Datenbank mit Dateien erstellen können, die Sie in Echtzeit aktualisieren können.

3

Teilen und erobern? Angenommen, ein MP os und Prozessor spawnen mehrere find Befehle für jeden Unterordner.

for dir in /myDirWithThausandsofDirectories/* 
do find "$dir" -name "*.suffix" & 
done 

abhängig von der Anzahl der subdirs Sie können steuern, wie viele Prozesse (find Befehle) zu einem bestimmten Zeitpunkt ausgeführt werden. Das wird ein bisschen schwieriger, aber machbar (dh mit einer Bash-Shell, halten Sie ein Array mit den PIDs der erzeugten Prozesse $! und erlauben nur neue, abhängig von der Länge des Arrays). Auch die oben genannten sucht nicht nach Dateien im Stammverzeichnis, nur ein kurzes Beispiel für die Idee.

Wenn Sie nicht wissen, wie die Verwaltung zu tun ist, Zeit zu lernen;) This ist ein wirklich guter Text zu diesem Thema. This ist, was Sie eigentlich brauchen. Aber lesen Sie das Ganze, um zu verstehen, wie es funktioniert.

+0

Sie können auch Dinge wie 'nice' und' ionice' betrachten, um Ihrem Skript eine höhere Priorität zu geben, aber ich bin mir nicht sicher, ob dies einen großen Unterschied machen wird und die Maschine höchstwahrscheinlich für andere Dinge unbrauchbar machen wird. – c00kiemon5ter

+0

Ich weiß nicht, wie man die Anzahl der Prozesse steuert! – Amir

+1

Ich habe meine Antwort bearbeitet um zu helfen :) – c00kiemon5ter

0

Da Sie einen einfachen Glob verwenden, können Sie Bashs rekursive Globbing verwenden. Beispiel:

shopt -s globstar 
for path in /etc/**/**.conf 
do 
    echo "$path" 
done 

könnte schneller sein, da sie mit viel weniger Flexibilität als find eine interne Shell-Fähigkeit ist verwenden.

Wenn Sie nicht Bash verwenden, aber Sie haben eine Grenze für die Pfadtiefe, können Sie explizit die verschiedenen Tiefen Liste:

for path in /etc/*/*.conf /etc/*/*/*.conf /etc/*/*/*/*.conf 
do 
    echo "$path" 
done 
0

Hier ist der Code:

find /myDirWithThausandsofDirectories/ -d type maxdepth 1 > /tmp/input 
IFS=$'\n' read -r -d '' -a files < /tmp/input 


do_it() { 
    for f; do find $f -name *.suffix | sed -e s/\.suffix//g ; done 
} 

# Divide the list into 5 sub-lists. 
i=0 n=0 a=() b=() c=() d=() e=() 
while ((i < ${#files[*]})); do 
    a[n]=${files[i]} 
    b[n]=${files[i+1]} 
    c[n]=${files[i+2]} 
    d[n]=${files[i+3]} 
    e[n]=${files[i+4]} 
    ((i+=5, n++)) 
done 

# Process the sub-lists in parallel 
do_it "${a[@]}" >> /tmp/f.unsorted 2>/tmp/f.err & 
do_it "${b[@]}" >> /tmp/f.unsorted 2>/tmp/f.err & 
do_it "${c[@]}" >> /tmp/f.unsorted 2>/tmp/f.err & 
do_it "${d[@]}" >> /tmp/f.unsorted 2>/tmp/f.err & 
do_it "${e[@]}" >> /tmp/f.unsorted 2>/tmp/f.err & 
wait 
echo Find is Done! 

Die Das einzige Problem, das ich damit habe, sind einige der Dateinamen (sehr kleiner Prozentsatz) sind teilweise aus. Ich habe keine Ahnung, was der Grund wäre!