13 Stimmen

Unix find: Liste der Dateien von stdin

Ich arbeite mit Linux & Bash (oder Cygwin & Bash).

Ich habe eine große riesig -Verzeichnisstruktur, und ich muss ein paar Nadeln im Heuhaufen finden.

Konkret suche ich nach diesen Dateien (etwa 20):

foo.c
bar.h
...
quux.txt

Ich weiß, dass sie sich in einem Unterverzeichnis irgendwo unter . .

Ich weiß, dass ich jeden von ihnen finden kann mit find . -name foo.c -print . Die Ausführung dieses Befehls dauert ein paar Minuten.

Wie kann ich die Namen dieser Dateien mit ihrem vollständigen Verzeichnisnamen ausdrucken? Ich möchte nicht 20 verschiedene find Das wird zu lange dauern.

Kann ich die find die Liste der Dateien von stdin? Aus einer Datei? Gibt es einen anderen Befehl, der das tut, was ich will?

Muss ich zuerst eine Befehlszeile für find con -o mit einer Schleife oder so?

12voto

jm666 Punkte 58205

Wenn Ihre Verzeichnisstruktur sehr groß ist, sich aber nicht häufig ändert, ist es sinnvoll, die Funktion

cd /to/root/of/the/files
find . -type f -print > ../LIST_OF_FILES.txt #and sometimes handy the next one too
find . -type d -print > ../LIST_OF_DIRS.txt

danach kann man wirklich SCHNELL alles finden (mit grep, sed, etc..) und die Dateilisten nur aktualisieren, wenn der Baum geändert wird. (es ist ein vereinfachter Ersatz, wenn Sie nicht über locate )

Also,

grep '/foo.c$' LIST_OF_FILES.txt #list all foo.c in the tree..

Wenn Sie eine Liste von Dateien finden wollen, können Sie Folgendes versuchen:

fgrep -f wanted_file_list.txt < LIST_OF_FILES.txt

oder direkt mit dem Befehl find

find . type f -print | fgrep -f wanted_file_list.txt

die -f für fgrep bedeutet - Muster aus der Datei zu lesen, so dass man leicht nach mehreren Mustern suchen kann...

4voto

pavium Punkte 14270

Sie sollten nicht laufen müssen find zwanzig Mal.

Sie können einen einzelnen Befehl mit mehreren Dateinamensangaben konstruieren:

find . \( -name 'file1' -o -name 'file2' -o -name 'file3' \) -exec echo {} \;

2voto

sarnold Punkte 99402

Ist die locate(1) Befehl eine akzeptable Antwort? Nachts wird ein Index erstellt, und Sie können den Index recht schnell abfragen:

$ time locate id_rsa
/home/sarnold/.ssh/id_rsa
/home/sarnold/.ssh/id_rsa.pub

real    0m0.779s
user    0m0.760s
sys 0m0.010s

Ich habe es aufgegeben, eine ähnliche find Befehl in meinem Home-Verzeichnis bei 36 Sekunden :)

Wenn nightly nicht funktioniert, können Sie die updatedb(8) einmal von Hand, bevor Sie das Programm locate(1) Rückfragen. /etc/updatedb.conf ( updatedb.conf(5) ) können Sie bestimmte Verzeichnisse oder Dateisystemtypen auswählen, um sie ein- oder auszuschließen.

1voto

0voto

marco Punkte 1

Hier ist eine Möglichkeit, eine Liste von Dateien aus stdin zu verarbeiten und Ihren (FreeBSD) find-Befehl so zusammenzustellen, dass er erweiterte reguläre Ausdrücke verwendet (n1|n2|n3) .

Für GNU find müssen Sie möglicherweise eine der folgenden Optionen verwenden, um den erweiterten Abgleich regulärer Ausdrücke zu aktivieren:

-regextype posix-egrep

-regextype posix-extended

echo '
foo\\.c
bar\\.h
quux\\.txt
' | xargs bash -c '
IFS="|"; 
find -E "$PWD" -type f -regex "^.*/($*)$" -print
echo find -E "$PWD" -type f -regex "^.*/($*)$" -print
' arg0

# note: "$*" uses the first character of the IFS variable as array item delimiter
(
IFS='|'
set -- 1 2 3 4 5
echo "$*"   # 1|2|3|4|5
)

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