bash - 查找结果的最佳方法是什么?

时间:2013-03-27 16:07:58

标签: bash find

我当前的解决方案是find <expr> -exec printf '.' \; | wc -c,但是当结果超过10000时,这需要太长时间。有没有更快/更好的方法来做到这一点?

5 个答案:

答案 0 :(得分:112)

为什么不

find <expr> | wc -l

作为简单的便携式解决方案?您的原始解决方案为找到的每个文件生成一个新进程 printf,这非常昂贵(正如您刚刚发现的那样)。

请注意,如果你有嵌入换行符的文件名,这将会超额计算,但如果你有,那么我怀疑你的问题会更深入: - )

答案 1 :(得分:53)

请尝试此操作(需要find的{​​{1}}支持):

-printf

它比计算线条更可靠,更快。

请注意,我使用find <expr> -type f -printf '.' | wc -c 的{​​{1}},而不是外部命令。


让我们坐一会儿:

find

我的代码段基准:

printf

全线:

$ ls -1
a
e
l
ll.sh
r
t
y
z

所以我的解决方案更快=)(重要的部分是$ time find -type f -printf '.' | wc -c 8 real 0m0.004s user 0m0.000s sys 0m0.007s 行)

答案 2 :(得分:2)

这是我countfiles中的~/.bashrc函数(速度相当快,适用于Linux&amp; FreeBSD find,并且不会被包含换行符的文件路径所欺骗;最终wc只计算NUL字节):

countfiles () 
{ 
   command find "${1:-.}" -type f -name "${2:-*}" -print0 | 
       command tr -dc '\0' | command wc -c;
return 0
}

countfiles

countfiles ~ '*.txt'

答案 3 :(得分:2)

此解决方案肯定比其他一些find -> wc解决方案慢,但如果除了计算文件名之外你还倾向于使用文件名做其他事情,你可以read来自{ {1}}输出。

find

这只是对BashGuide中a solution的修改,它通过使用n=0 while read -r -d ''; do ((n++)) # count # maybe perform another act on file done < <(find <expr> -print0) echo $n 使find输出分隔符成为NUL字节并使用{读取它来正确处理具有非标准名称的文件{1}}(NUL字节)作为循环分隔符。

答案 4 :(得分:-2)

我喜欢偶然发现速度比赛。使用wc没什么问题,但只要我们进行基准测试 - 这是(我认为)最便携,最快的解决方案:``

$ time (i=0; for d in /dev/sd*[a-z]; do ((i++)); done; echo $i)
25

real    0m0.001s
user    0m0.000s
sys     0m0.000s

与使用find / wc相比:

$ time find /dev/sd*[a-z] | wc -l
25

real    0m0.006s
user    0m0.000s
sys     0m0.004s

$ time find /dev/sd*[a-z] -printf . | wc -c
25

real    0m0.005s
user    0m0.000s
sys     0m0.000s

请注意,如果您需要考虑隐藏文件,那么您的for循环中必须有2个参数:for devfile in /dev/.* /dev/*; do ...并且它仍然更快。

快乐的黑客攻击!