无法在 CentOS 中执行 运行 cat 命令(参数列表太长)

Unable to run cat command in CentOS (argument list too long)

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

的计数

我的命令:

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

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

Argument too long

参数列表的最大大小各不相同,但通常约为 128 KiB 或 256 KiB。这意味着如果 *20200119* 部分溢出最大参数列表,您将拥有大量文件。但是你说 "around 3 lakhs files",大约是 300,000 — 每个文件中至少包含 8 个字符的日期字符串,加上足够多的其他字符来使名称唯一,因此文件名列表对于即使是最大的合理 'maximum argument list size'.

请注意,您命令的 nohup cat 部分不合理(请参阅 UUoC: Useless Use of Cat);您应该使用 grep '{' *20200119* 来避免不必要地通过管道传输所有数据。但是,这也会 运行 导致参数列表太长的问题。

您可能必须使用以下命令的变体才能在不溢出命令行的情况下获得所需的结果:

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

这使用了 POSIX find 的特性,将尽可能多的参数分组到命令行中,而不会溢出到 运行 grep 大(但不是too large) 文件数量,然后将 grep 命令的输出传递给 wc。如果您担心输出中出现的文件名,请使用 grep -h.

抑制它们

或者您可以使用:

find . -depth 1 -name '*20200119*' -exec grep  -c -h '{' {} + |
awk '{sum += } 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 一起使用可能会得到更好的错误消息。 =36=]

请您尝试以下操作:

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 选项。