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
с помощью цикла или чего-то еще?
Ответы
Ответ 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)
) позволяет вам выбирать определенные каталоги или типы файловой системы для включения или исключения.
Ответ 4
Да, собрать свою командную строку.
Ответ 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
)