Maildir 目录中的 Bash 脚本

Maildir 目录中的 Bash 脚本

我想对 Maildir 目录中的 500 个文件进行 grep 处理。我发出命令

grep MyPattern *

我收到错误消息:

bash: /usr/bin/grep: Argument list too long

所以我将文件列表存储在文件 MyFiles 中,并发出以下命令

for i in $(`cat MyFiles`); do echo $i; done

在执行 grep 之前,我想做一个 echo 来进行检查。但这给出了以下错误

bash: 1434361691.M617282P6399V0000000000000808I00000000000E16C1_23.ananda-linux,S=10055:2,S: command not found

其中 1434... 是目录中的第一个文件。

那么回到原来的问题。如何 grep 查找邮箱中的所有这些文件。我有更大的邮箱,包含 50000 封或更多电子邮件。

答案1

要求grep自己通过从当前目录递归来构造文件列表:

grep -r MyPattern .

这与 不太一样*,因为它会在子目录中搜索,但对于邮件目录,这通常是您想要的。

答案2

当 shell 执行外部命令时,在扩展任何文件名通配模式(例如 )之后,命令行的长度*不得超过特定长度。

在您的情况下,grep 'PATTERN' *扩展为 shell 无法执行的太长的命令。

在你的第二个例子中:

for i in $(`cat MyFiles`); do echo $i; done

您尝试迭代存储在 中的文件名MyFiles,但语法非常错误。

$(`cat MyFiles`)

是相同的

$( $(cat MyFiles) )

这意味着 的内容MyFiles将被解释为命令。这就是您收到command not found错误的原因。

有多种方法可以解决此问题,但是循环遍历文件内容并不是一个好的方法。

斯蒂芬给出了一个很好的解决方案在他的回答中,另一种是,假设您当前的工作目录是 Maildir 文件夹,

find . -type f -exec grep 'PATTERN' {} +

这将grep在大批量文件上执行几次尽可能

这类似于

printf '%s\n' * | xargs grep 'PATTERN'

但该find命令处理带有空格和嵌入换行符的文件名。

这里的命令printf将每行输出一个文件名。它不会遇到同样的问题,因为grep 'PATTERN' *它很可能是内置命令,因此不必由 shell 作为外部命令执行。

cat您的循环解决方案也可以工作,但您可以简单地执行以下操作,而不是循环 的输出

for name in *; do
    grep 'PATTERN' "$name"
done

这假设有仅常规文件在当前目录中。

为了确保您只处理邮件消息,您可以使用

for name in *,*; do
    grep 'PATTERN' "$name" /dev/null
done

这会迭代至少包含一个逗号的名称。我还添加了/dev/null强制grep输出与给定模式匹配的文件的名称。如果您支持的话,您可以删除/dev/null并改为使用-Hwith 。grepgrep

这样的循环很慢,因为我们grep对目录中的每个文件执行一次。

相关内容