尝试访问ls *.txt | wc -l
包含许多文件的目录时出现以下错误:
-bash: /bin/ls: Argument list too long
此“参数列表”的阈值是否取决于发行版或计算机规格?通常,我wc -l
会将如此大结果的结果传递给其他一些命令(例如),因此我不关心终端的限制。
尝试访问ls *.txt | wc -l
包含许多文件的目录时出现以下错误:
-bash: /bin/ls: Argument list too long
此“参数列表”的阈值是否取决于发行版或计算机规格?通常,我wc -l
会将如此大结果的结果传递给其他一些命令(例如),因此我不关心终端的限制。
Answers:
你的错误信息参数列表太长来自*的ls *.txt
。
对于二进制程序和您的内核,此限制都是安全的。您将在此页面上看到有关它的更多信息,以及如何使用和计算它。
管道尺寸没有这种限制。因此,您可以简单地发出以下命令:
find -type f -name '*.txt' | wc -l
注意:在现代Linux上,文件名中的怪异字符(如换行符)将使用ls
或这类工具进行转义find
,但仍从*显示。如果您使用的是旧版Unix,则需要此命令
find -type f -name '*.txt' -exec echo \; | wc -l
NB2:我想知道如何创建一个名称中带有换行符的文件。一旦知道了窍门,它并不难:
touch "hello
world"
-maxdepth 1
如果您不打算计算子目录中的文件,则可能还需要添加一个。
-exec echo \;
。
find
。将find
在OS X和基于busybox的系统,和我猜想的任何基于BSD的系统显示,在这一个换行符,这会惹计数的文件名。
wc -l
正在计算换行符。因此,我们希望它具有换行符。
它主要取决于您的Linux内核版本。
您应该能够通过运行查看系统的限制
getconf ARG_MAX
它告诉您命令行被shell扩展后可以具有的最大字节数。
在Linux <2.6.23中,限制通常为128 KB。
在Linux> = 2.6.25中,限制为128 KB或堆栈大小的1/4(请参阅ulimit -s
参考资料),以较大者为准。
有关所有详细信息,请参见execve(2)手册页。
不幸的是,管道ls *.txt
无法解决问题,因为限制是在操作系统中,而不是外壳中。
Shell展开*.txt
,然后尝试调用
exec("ls", "a.txt", "b.txt", ...)
而且您匹配的文件太多*.txt
,超出了128 KB的限制。
您必须做类似的事情
find . -maxdepth 1 -name "*.txt" | wc -l
代替。
(并参阅下面的Shawn J. Goff关于包含换行符的文件名的评论。)
.
和-maxdepth 1
意思吗?谢谢!:D
.
表示当前目录,-maxdepth 1
表示它不在子目录中。目的是与匹配相同的文件*.txt
。
另一个解决方法:
ls | grep -c '\.txt$'
即使ls
产生的输出多于ls *.txt
产生(或尝试产生)的输出,它也不会遇到“参数过长”的问题,因为您没有将任何参数传递给ls
。请注意,grep
它采用正则表达式而不是文件匹配模式。
您可能要使用:
ls -U | grep -c '\.txt$'
(假设您的ls
支持版本支持此选项)。这告诉您ls
不要对输出进行排序,这样可以节省时间和内存-在这种情况下,顺序无关紧要,因为您只是在计数文件。排序输出所花费的资源通常并不重要,但是在这种情况下,我们已经知道您有很多*.txt
文件。
而且,您应该考虑重新组织文件,以使单个目录中没有太多文件。这可能可行,也可能不可行。
MAX_ARG_PAGES似乎是内核参数。使用find
和xargs
是解决此限制的典型组合,但我不确定它是否适用wc
。
将输出的find . -name \*\.txt
文件发送到文件中并计算该文件中的行数应作为解决方法。
ls
的输出执行任何操作,但无法解决此问题。只要* .txt通配符超出限制,在启动ls
和生成任何输出之前都将失败。
ls
您应该指定-maxdepth 1
避免递归扫描子目录。
ls
输出,这是一个坏主意,因此最好避免使用它。有关计数的信息,请参见计算目录中文件数量的最佳方法是什么?,有关棘手的解决方法,请参见为什么for循环不会引发“参数过长”错误?。