繁体   English   中英

在 linux 的目录中查找与模式匹配的文件数

[英]Find count of files matching a pattern in a directory in linux

我是 linux 的新手。我在 linux 中有一个目录,其中包含大约 250,000 个文件,我需要查找与模式匹配的文件数。

我尝试使用以下命令:

ls -1 20061101-20131101_kh5x7tte9n_2010_* | wc -l

我收到以下错误消息:

-bash: /bin/ls: Argument list too long
0

请帮忙。 提前致谢

为此使用find可能会更好:

find . -name "pattern_*" -printf '.' | wc -m

在您的具体情况下:

find . -maxdepth 1 -name "20061101-20131101_kh5x7tte9n_2010_*" -printf '.' | wc -m

find将返回符合条件的文件列表。 -maxdepth 1将使搜索仅在路径中完成,没有子目录( 感谢 Petesh! )。 -printf '.' 将为每个匹配打印一个点,以便带有新行的名称不会使wc -m中断。

然后wc -m将指示与文件数匹配的字符数。


两种可能选项的性能比较:

让我们用这种模式创建 10 000 个文件:

$ for i in {1..10000}; do touch 20061101-20131101_kh5x7tte9n_201_$i; done

然后将获得结果所需的时间与ls -1 ...find ...

$ time find . -maxdepth 1 -name "20061101-20131101_kh5x7tte9n_201_*" | wc -m
10000

real    0m0.034s
user    0m0.017s
sys     0m0.021s

$ time ls -1 | grep 20061101-20131101_kh5x7tte9n_201 | wc -m
10000

real    0m0.254s
user    0m0.245s
sys     0m0.020s

find快了 5 倍! 但是如果我们使用ls -1f再次感谢 Petesh! ),那么ls甚至比find更快:

$ time ls -1f | grep 20061101-20131101_kh5x7tte9n_201 | wc -m
10000

real    0m0.023s
user    0m0.020s
sys     0m0.012s

你得到了“参数太长”,因为 shell 将你的模式扩展到文件列表。 尝试:

find  -maxdepth 1 -name '20061101-20131101_kh5x7tte9n_2010_*' |wc -l

请注意 - 模式用引号括起来以防止外壳扩展

做就是了:

find . -name "pattern_*" |wc -l

尝试这个:

ls -1 | grep 20061101-20131101_kh5x7tte9n_2010_ | wc -l

您通常应该避免在脚本中使用ls事实上,在 shell 函数中执行计算将避免“参数列表太长”错误,因为没有exec边界,因此ARGV_MAX限制不会起作用。

number_of_files () {
    if [ -e "$1" ]; then
        echo "$#"
    else
        echo 0
    fi
}

条件防止 glob 根本没有扩展(这是开箱即用的默认设置;在 Bash 中,您可以shopt -s nullglob使不匹配任何文件的通配符扩展为空字符串)。

尝试一下:

number_of_files 20061101-20131101_kh5x7tte9n_2010_*

MacOS/OS X 命令行解决方案

如果您尝试在 Mac 上的命令行中执行此操作,您很快就会发现find不支持-printf选项。

要实现与fedorqui-supports-monica提出的解决方案相同的结果,请尝试以下操作:

find . -name "pattern_*" -exec stat -f "." {} \; | wc -l

这将找到与您输入的模式匹配的所有文件,打印一个. 对于它们中的每一个在换行符中,然后最后计算行数并输出该数字。

使用 find 计算 MacOS 和 OS X 中匹配的文件名

要将搜索深度限制到当前目录,请将-maxdepth 1添加到命令中,如下所示:

find . -maxdepth 1 -name "196288.*" -exec stat -f "." {} \; | wc -l
ls -1 | grep '20061101-20131101_kh5x7tte9n_2010_*' | wc -l

先前的答案不包括搜索条件周围的引号,也不包括 * 通配符。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM