6

我试图清理一些垃圾邮件并遇到了问题。队列中的文件数量太大,以至于我通常的命令无法处理。它会给我一个关于太多论点的错误。

我通常这样做

grep -i user@domain.com 1US* | awk -F: '{print $1}' | xargs rm

1US* 可以是 1US[a-zA-Z] 之间的任何值。我唯一能做的就是运行这个可怕的装置。它的一个文件,包括 1USa、1USA、1USb 等,贯穿整个字母表。我知道他们必须是一种更有效地运行它的方法。

grep -s $SPAMMER /var/mailcleaner/spool/exim_stage1/input/1USa* | awk -F: '{print $1}' | xargs rm
grep -s $SPAMMER /var/mailcleaner/spool/exim_stage1/input/1USA* | awk -F: '{print $1}' | xargs rm
4

5 回答 5

2

您可以使用它find来查找名称以模式“1US”开头的所有文件。然后,您可以将输出通过管道传输到 xargs ,这将确保参数列表不会增长太多并处理 grep 调用。请注意,我使用空字节来分隔 xargs 的文件名。这避免了有问题的文件名的问题。;)

find -maxdepth 1 -name '1US*' -printf '%f\0' | xargs -0 grep -u user@domain | awk ...
于 2013-04-18T15:22:06.050 回答
2

运行几个 grep 实例。代替

grep -i user@domain.com 1US* | awk '{...}' | xargs rm

(for i in 1US*; do grep -li user@domain "$i"; done) | xargs rm

注意 -l 标志,因为我们只需要匹配的文件名。这将加快 grep(在第一次匹配时终止)并使您的 awk 脚本不再需要。这可以通过检查 grep 的返回状态并调用 rm 来改进,而不是使用 xargs(xargs 非常脆弱,IMO)。如果你问,我会给你更好的版本。

希望能帮助到你。

于 2013-04-18T15:58:01.170 回答
1

使用 xargs 比使用“find ... -exec grep”更有效,因为您创建的进程更少等。

解决此问题的一种方法是:

ls 1US* | xargs grep -i user@domain.com | awk -F: '{print $1}' | xargs rm

但更容易的是:

find . -iname "1US*" -exec rm {} \;
于 2013-04-18T18:29:19.610 回答
1

-exec参数在find这里很有用,我自己在类似的情况下使用过这个。

例如

# List the files that match
find /path/to/input/ -type f -exec grep -qiF spammer@spammy.com \{\} \; -print
# Once you're sure you've got it right
find /path/to/input/ -type f -exec grep -qiF spammer@spammy.com \{\} \; -delete
于 2013-04-18T15:53:28.623 回答
0

使用findand 循环代替xargs.

find . -name '1US*' | \
while read x; do grep -iq user@domain "$x" && rm "$x"; done

这使用管道和循环而不是参数(forgreprm),并防止与参数限制相关的问题。

于 2013-04-18T16:23:20.377 回答