查找 Linux 目录中匹配模式的文件数量

问题描述 投票:0回答:8

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

我尝试使用以下命令:

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

我收到以下错误消息:

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

请帮忙。预先感谢

regex linux bash find ls
8个回答
71
投票

为此使用

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

6
投票

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

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

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


4
投票

MacOS / OS X 命令行解决方案

如果您尝试在 Mac 上的命令行中执行此操作,您很快就会发现

find
不支持
-printf
选项。

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

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

这将找到与您输入的模式匹配的所有文件,在换行符中为每个文件打印一个

.
,然后最后计算行数并输出该数字。

要将搜索深度限制为当前目录,请将

-maxdepth 1
添加到命令中,如下所示:

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

4
投票

就这样做:

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

2
投票

试试这个:

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

1
投票

您通常应该避免在脚本中使用

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_*

0
投票

首先最好不要根据this文章使用ls!!!

这个问题可以通过多种方式解决。我将列出一些我想到的最优雅的。

count=(*20061101-20131101_kh5x7tte9n_2010_*); count=${#count[@]}

或者

count=$(file *20061101-20131101_kh5x7tte9n_2010_* | wc -l)

或者

count=$(echo *20061101-20131101_kh5x7tte9n_2010_* | wc -w)

或者

count=$(stat -c "%n" *20061101-20131101_kh5x7tte9n_2010_* | wc -l)

或者

count=$(du -a *20061101-20131101_kh5x7tte9n_2010_* | wc -l)

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

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

© www.soinside.com 2019 - 2024. All rights reserved.