bash 计算“查找”结果的最佳方法是什么?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/15663607/
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

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-09 23:30:19  来源:igfitidea点击:

What is the best way to count "find" results?

bashfind

提问by MechMK1

My current solution would be find <expr> -exec printf '.' \; | wc -c, but this takes far too long when there are more than 10000 results. Is there no faster/better way to do this?

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

采纳答案by Gilles Quenot

Try this instead (require find's -printfsupport):

试试这个(需要find-printf支持):

find <expr> -type f -printf '.' | wc -c

It will be more reliable and faster than counting the lines.

它将比计算线路更可靠、更快。

Note that I use the find's printf, not an external command.

请注意,我使用的是find's printf,而不是外部命令。



Let's bench a bit :

让我们稍作休息:

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

My snippet benchmark :

我的片段基准:

$ time find -type f -printf '.' | wc -c
8

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

With full lines :

全线:

$ time find -type f | wc -l
8

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

So my solution is faster =) (the important part is the realline)

所以我的解决方案更快=)(重要的部分是real线路)

回答by Brian Agnew

Why not

为什么不

find <expr> | wc -l

as a simple portable solution ? Your original solution is spawning a new processprintffor every individual file found, and that's very expensive (as you've just found).

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

Note that this will overcount if you have filenames with newlines embedded, but if you have that then I suspect your problems run a little deeper :-)

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

回答by John B

This solution is certainly slower than some of the other find -> wcsolutions here, but if you were inclined to do something else with the file names in addition to counting them, you could readfrom the findoutput.

这个解决方案肯定比find -> wc这里的其他一些解决方案慢,但是如果除了计算文件名之外,您还倾向于对文件名做其他事情,您可以readfind输出中获取。

n=0
while read -r -d ''; do
    ((n++)) # count
    # maybe perform another act on file
done < <(find <expr> -print0)
echo $n

It is just a modification of a solutionfound in BashGuide that properly handles files with nonstandard names by making the findoutput delimiter a NUL byte using print0, and reading from it using ''(NUL byte) as the loop delimiter.

它只是对 BashGuide 中找到的解决方案的修改,该解决方案通过使用 将find输出定界符设为NUL 字节print0,并使用''(NUL 字节) 作为循环定界符从中读取来正确处理具有非标准名称的文件。

回答by carlo

This is my countfilesfunction in my ~/.bashrc(it's reasonably fast, should work for Linux & FreeBSD find, and does not get fooled by file paths containing newline characters; the final wcjust counts NUL bytes):

这是我的countfiles函数~/.bashrc(它相当快,应该适用于 Linux 和 FreeBSD find,并且不会被包含换行符的文件路径所迷惑;最后wc只计算 NUL 字节):

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

countfiles

countfiles ~ '*.txt'