【问题标题】:Unable to run cat command in CentOS (argument list too long)在 CentOS 中无法运行 cat 命令(参数列表太长)
【发布时间】:2020-01-20 06:49:44
【问题描述】:

我有一个文件夹,其中包含大约 300k 个文件,每个文件包含 2-3mb 现在我想运行一个命令来查找 char { 在 shell 中的计数

我的命令:

nohup cat *20200119*| grep "{" | wc -l > /mpt_sftp/mpt_cdr_ocs/file.txt

这适用于少量文件 当我在拥有所有文件(300k 文件)的文件位置运行时,它会显示

参数太长

【问题讨论】:

    标签: linux bash centos


    【解决方案1】:

    请您尝试以下方法:

    find . -maxdepth 1 -type f -name "*20200119*" -print0 | xargs -0 grep -F -o "{" | wc -l > /mpt_sftp/mpt_cdr_ocs/file.txt
    

    我实际测试了 300,000 个 10 个字符长的文件名,并且运行良好。

    • xargs 自动调整提供给grep 的参数列表的长度,我们无需担心。 (您可以通过将-t 选项置于xargs 来查看grep 命令的执行方式。)
    • -F 选项大大加快了 grep 的执行速度,以搜索固定字符串,而不是正则表达式。
    • 如果字符 { 在一行中出现多次并且您想单独计算它们,则需要 -o 选项。

    【讨论】:

    • @JonathanLeffler 感谢您纠正错字。
    【解决方案2】:

    参数列表的最大大小各不相同,但通常为 128 KiB 或 256 KiB。这意味着如果*20200119* 部分溢出最大参数列表,您将拥有大量文件。但是您说“大约 30 万个文件”,即大约 300,000 个——每个文件中至少包含 8 个字符的日期字符串,加上足够的其他字符以使名称唯一,因此文件名列表将太长即使是最大的合理“最大参数列表大小”。

    请注意,您的命令的nohup cat 部分是不明智的(请参阅UUoC: Useless Use of Cat);您应该使用grep '{' *20200119* 来节省不必要地通过管道传输所有数据。但是,这也会遇到参数列表过长的问题。

    您可能必须使用以下命令的变体来获得所需的结果,而不会溢出您的命令行:

    find . -depth 1 -name '*20200119*' -exec grep '{' {} + | wc -l
    

    这使用了 POSIX find 的特性,它将尽可能多的参数组合到命令行中,而不会溢出以在大量(但不是太大)文件上运行 grep,然后传递grep 命令到 wc。如果您担心输出中出现的文件名,请使用 grep -h 隐藏它们。

    或者你可以使用:

    find . -depth 1 -name '*20200119*' -exec grep  -c -h '{' {} + |
    awk '{sum += $1} END {print sum}'
    

    macOS 上的grep -c -h 在其参数列表中列出的每个文件的标准输出中生成一个简单数字(包含至少一个{ 的行数); GNU grep 也是如此。 awk 脚本将这些数字相加并打印结果。

    在 macOS 上 find 支持使用 -depth 1-maxdepth 1 也是如此——它们是等价的。 GNU find 似乎不支持 -depth 1。最好使用-maxdepth 1。 POSIX find 仅支持 -depth 没有编号。与使用 -depth 1 相比,使用 -maxdepth 1 和仅支持 POSIX 的最少选项集的 find 可能会得到更好的错误消息。

    【讨论】:

    • OP 说有 30 万个文件。那是 300,000。
    • @rici — 错过了;这是很多名称,其中包含相同的 8 字符日期字符串。因此,肯定会溢出任何合理的“最大参数列表”大小。
    猜你喜欢
    • 1970-01-01
    • 2014-04-08
    • 2013-05-30
    • 2015-10-30
    • 1970-01-01
    • 1970-01-01
    • 2014-12-03
    • 2014-08-24
    • 1970-01-01
    相关资源
    最近更新 更多