【问题标题】:Most efficient way to grep files in directories for deletion using bash/aliases使用 bash/aliases 对目录中的文件进行 grep 删除的最有效方法
【发布时间】:2018-10-04 17:58:58
【问题描述】:

我有一个托管多个虚拟域和用户的 Debian 虚拟专用服务器。它的配置是为了托管多个域并在每个域名下拥有多个电子邮件地址(用户或帐户)。

我确实经常收到垃圾邮件,没有时间查看SpamAssasin,了解如何根据电子邮件正文中的匹配字符串过滤某些电子邮件。

相反,.bash_aliases 中添加了以下函数,并为快速访问使用了别名

my_new_del() {
  echo "0:  $1"
  for d in /home/vmail/*/ ; do
      # echo "1:  $d"
      for f in "$d"info/*/*.some.file.pattern*;do
          grep -i -H -l -s "$1" "$f" | while read -r line ; do
              echo "rm -rf $line"
              rm -rf $line
          done
          # echo "2:  $f"
      done
  done
}
alias my_del=my_new_del

那我就用上面的别名:

my_del 'some string' &

脚本完成了这项工作,但它确实很慢,而且似乎效率低下。它循环遍历 vmail 目录中的每个子目录(每个子目录代表一个域名)。然后它遍历每个子目录中的文件,然后对字符串进行 greps - 如果匹配,则将其删除。

这能以更有效的方式完成吗?

【问题讨论】:

  • 编辑您的 Q 以说明/home/vmail 目录下有多少文件。看起来您每次都在重新处理所有文件来运行它,所以如果您能找到一种方法来隐藏/移动干净的文件,然后只扫描新文件,那应该会显着加快您的进程。祝你好运。
  • 您似乎为每个可能很小的文件调用一次grep。这比让grep 同时搜索多个文件要慢得多。
  • @thatotherguy grep 如何搜索多个文件?我假设如果你运行grep 'string' *,它仍然会遍历目录中的文件,不是吗?
  • 问的重点是,如果您有一千个、一百万个或十亿个文件,方法可能会有所不同。您不会确切知道有多少,但您会知道几个数量级。
  • wrt I assumed that if you run grep 'string' * it will still loop through the files in the directory - grep string *for f in *; do grep string "$f"; done 之间的性能差异很大。在前者中,您只要求 shell 生成一次 grep 进程(一项耗时的任务),而在后者中,shell 每个文件生成一次。再次,请参阅why-is-using-a-shell-loop-to-process-text-considered-bad-practice 了解详情。

标签: bash grep debian spam


【解决方案1】:

您没有提供任何示例输入/输出,因此未经测试,但听起来这就是您想要做的:

my_new_del() {
    find /home/vmail -type f -name '*.some.file.pattern*' -exec grep -i -H -l -s "$1" {} + |
    xargs rm -f {}
}

我假设您的文件名不包含任何空格,因为您现有的脚本依赖于该假设。

【讨论】:

  • 样本输入输出是什么?有文件,且文件内容与'some string' 匹配或不匹配。它就在问题本身。您的答案比我目前的答案更有效率吗?我的解决方案也有效。
  • 输入:在包含 3 个文件的目录上运行 ls 的结果 + 在每个文件上运行 cat 的结果以显示其中一个或 2 个确实包含目标字符串而另一个(s) 不要。输出:ls 的结果再次显示预期的文件已被删除。怎样更有效率?因为它避免了嵌套循环(包括最里面的while read)和无关命令,所以它的效率将提高几个数量级。有关 shell 循环的一些问题,请参阅 why-is-using-a-shell-loop-to-process-text-considered-bad-practice
  • 您的原始脚本很慢,主要是因为它对每个文件进行了 2 个分叉。这个版本每个文件只做约 0.001 个分叉。它应该会快得多。
  • 不,这与此解决方案无关。它使用 xargs 和 find -exec + 来避免它。
  • 像魅力一样工作。我确实使用time 命令调用了别名函数来计时执行。原始脚本运行在:real 3m19.912s user 0m16.260s sys 0m25.832s 新修改的脚本运行在real 0m6.008s user 0m4.588s sys 0m0.684s。很大的进步。谢谢
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-07-31
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-08-25
  • 2014-09-23
相关资源
最近更新 更多