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

时间:2014-01-15 16:35:52

标签: regex linux bash find ls

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

我尝试使用以下命令:

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

我收到以下错误消息:

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

请帮忙。提前致谢

6 个答案:

答案 0 :(得分:38)

最好使用find

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

在您的具体案例中:

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

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

然后wc -l将指示行数。


两种可能选择的绩效比较:

让我们用这种模式创建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 -l
10000

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

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

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

find快了x5倍!但是,如果我们使用ls -1fthanks Petesh again!),那么ls甚至会比find更快:

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

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

答案 1 :(得分:2)

试试这个:

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

答案 2 :(得分:2)

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

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

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

答案 3 :(得分:1)

通常应该avoid ls in scripts,实际上,在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_*

答案 4 :(得分:0)

MacOS / OS X命令行解决方案

如果您尝试在Mac上的命令行中执行此操作,很快就会发现find选项是-printf does not support

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

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

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

Using find to count matching filenames in MacOS and OS X

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

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

答案 5 :(得分:-3)

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

之前的回答未包含搜索条件的引号,也不包含*通配符。