bash Unix 查找:来自标准输入的文件列表
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/6185994/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Unix find: list of files from stdin
提问by JXG
I'm working in Linux & bash (or Cygwin & bash).
我在 Linux 和 bash(或 Cygwin 和 bash)中工作。
I have a huge--huge--directory structure, and I have to find a few needles in the haystack.
我有一个巨大的——巨大的——目录结构,我必须在大海捞针中找到几根针。
Specifically, I'm looking for these files (20 or so):
具体来说,我正在寻找这些文件(20 个左右):
foo.c
bar.h
...
quux.txt
I know that they are in a subdirectory somewhere under ..
我知道它们位于..
I know I can find any one of them with
find . -name foo.c -print. This command takes a few minutes to execute.
我知道我可以找到其中的任何一个
find . -name foo.c -print。此命令需要几分钟才能执行。
How can I print the names of these files with their full directory name? I don't want to execute 20 separate finds--it will take too long.
如何使用完整目录名打印这些文件的名称?我不想执行 20 个单独find的 s——它会花费太长时间。
Can I give findthe list of files from stdin? From a file? Is there a different command that does what I want?
我可以提供find来自标准输入的文件列表吗?从文件?是否有不同的命令可以执行我想要的操作?
Do I have to first assemble a command line for findwith -ousing a loop or something?
我必须先组装一个命令行对find与-o使用循环或东西吗?
采纳答案by jm666
If your directory structure is huge but not changing frequently, it is good to run
如果你的目录结构很大但不经常变化,运行就好
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
after it you can really FAST find anything (with grep, sed, etc..) and update the file-lists only when the tree is changed. (it is a simplified replacement if you don't have locate)
在它之后,您可以真正快速地找到任何东西(使用 grep、sed 等)并仅在树更改时更新文件列表。(如果你没有,它是一个简化的替代品locate)
So,
所以,
grep '/foo.c$' LIST_OF_FILES.txt #list all foo.c in the tree..
When want find a list of files, you can try the following:
当想要查找文件列表时,您可以尝试以下操作:
fgrep -f wanted_file_list.txt < LIST_OF_FILES.txt
or directly with the find command
或直接使用 find 命令
find . type f -print | fgrep -f wanted_file_list.txt
the -ffor fgrep mean - read patterns from the file, so you can easily grepping input for multiple patterns...
在-f对fgrep一样均值-从文件中读取模式,让您可以轻松grepping输入的多模式...
回答by pavium
You shouldn't need to run findtwenty times.
你不应该需要跑find二十次。
You can construct a single command with a multiple of filename specifiers:
您可以使用多个文件名说明符构造单个命令:
find . \( -name 'file1' -o -name 'file2' -o -name 'file3' \) -exec echo {} \;
回答by sarnold
Is the locate(1)command an acceptable answer? Nightly it builds an index, and you can query the index quite quickly:
是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
I gave up executing a similar findcommand in my home directory at 36 seconds. :)
我find在 36 秒时放弃了在我的主目录中执行类似的命令。:)
If nightly doesn't work, you could run the updatedb(8)program by hand once before running locate(1)queries. /etc/updatedb.conf(updatedb.conf(5)) lets you select specific directories or filesystem types to include or exclude.
如果 nightly 不起作用,您可以updatedb(8)在运行locate(1)查询之前手动运行该程序一次。/etc/updatedb.conf( updatedb.conf(5)) 允许您选择要包含或排除的特定目录或文件系统类型。
回答by Ignacio Vazquez-Abrams
Yes, assemble your command line.
是的,组装你的命令行。
回答by marco
Here's a way to process a list of files from stdin and assemble your (FreeBSD) find command to use extended regular expression matching (n1|n2|n3).
这是一种处理来自 stdin 的文件列表并组合您的 (FreeBSD) find 命令以使用扩展正则表达式匹配的方法(n1|n2|n3)。
For GNU find you may have to use one of the following options to enable extended regular expression matching:
对于 GNU find,您可能必须使用以下选项之一来启用扩展正则表达式匹配:
-regextype posix-egrep
-regextype posix-egrep
-regextype posix-extended
-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
)

