Подтвердить что ты не робот

Unix find: список файлов из stdin

Я работаю в Linux и bash (или Cygwin и bash).

У меня огромная - структура каталогов, и мне нужно найти несколько игл в стоге сена.

В частности, я ищу эти файлы (примерно 20):

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

Я знаю, что они находятся в подкаталоге где-то под ..

Я знаю, что могу найти кого-нибудь из них с find . -name foo.c -print. Эта команда занимает несколько минут.

Как я могу напечатать имена этих файлов с их полным именем каталога? Я не хочу выполнять 20 отдельных find s - это займет слишком много времени.

Могу ли я дать find список файлов из stdin? Из файла? Есть ли другая команда, которая делает то, что я хочу?

Должен ли я сначала собрать командную строку для find с помощью -o с помощью цикла или чего-то еще?

4b9b3361

Ответ 1

Если структура вашего каталога огромна, но не часто меняется, полезно запустить

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

после этого вы можете действительно FAST найти что-нибудь (с grep, sed и т.д.) и обновить списки файлов только тогда, когда дерево будет изменено. (это упрощенная замена, если у вас нет locate)

Итак,

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

Когда вы хотите найти список файлов, вы можете попробовать следующее:

fgrep -f wanted_file_list.txt < LIST_OF_FILES.txt

или непосредственно с помощью команды find

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

the -f для fgrep mean - читайте паттерны из файла, поэтому вы можете легко выполнить grepping ввод для нескольких шаблонов...

Ответ 2

Вам не нужно запускать find двадцать раз.

Вы можете создать одну команду с несколькими спецификаторами имени файла:

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

Ответ 3

Является ли команда locate(1) приемлемым ответом? Ночью он строит индекс, и вы можете запросить индекс довольно быстро:

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

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

Я отказался от выполнения аналогичной команды find в моем домашнем каталоге через 36 секунд.:)

Если ночной режим не работает, вы можете запустить программу updatedb(8) вручную один раз перед запуском locate(1) запросов. /etc/updatedb.conf (updatedb.conf(5)) позволяет вам выбирать определенные каталоги или типы файловой системы для включения или исключения.

Ответ 5

Здесь вы можете обработать список файлов из stdin и собрать команду find (FreeBSD) для использования расширенного соответствия регулярному выражению (n1|n2|n3).

Для поиска GNU вам может потребоваться использовать один из следующих параметров, чтобы включить расширенное регулярное выражение:

-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
)