删除所有内容中不包含模式的文件

删除所有内容中不包含模式的文件

如何删除所有不包含指定文本的文件。

我了解删除具有指定文本的文件的解决方案,但我需要删除不包含指定模式的文件。

以下命令创建不包含“成功运行”的文件列表:

grep -c "successful run" *.out | grep -v ":1" > err.txt

我希望直接删除这些文件。

答案1

您最初的识别适当文件的方法是

grep -c "successful run" *.out | grep -v ":1"

存在缺陷。主要问题:

  • 如果一个文件中有两行或更多匹配的行怎么办?grep ":0"似乎更符合问题标题中的条件(“不包含模式的文件”)。
  • 如果文件名中有:1(或) 会怎么样?这样看起来就更好了。:0grep ':0$'
  • 如果从第一个传递的任何文件名中都有换行符怎么办grep

我说不要依赖grep -c;依赖退出状态,也grep就是1如果没有选择任何行。

for f in *.out; do
   [ -f "$f" ] && {
      grep -q -- "successful run" "$f"
      [ "$?" -eq 1 ] && rm -i -- "$f"
   }
done

笔记:

  • [ -f "$f" ] && …将不会让其grep与匹配的目录、fifo 等一起工作*.out;只能与常规文件一起工作。
  • --解释的含义和意义这里。万一有文件名以 开头-,它可能会误认为是选项。处理此问题的另一种方法是for f in ./*.out; do …。这样,每个扩展名都$f以 开头,./因此它不能以 开头-
  • rm -i以防万一使用了。测试解决方案后,您可能想要省略-i
  • grep … || rm …更糟糕。当发生真正的错误(例如权限被拒绝)时,退出状态grep大于1;那时您可能不想删除该文件。我的解决方案测试退出状态是否正好是1
  • 您的原始代码不会下降到子目录中,我的也不会。如果您想要递归,那么支持它的 shell(例如带有shopt -s globstar和 的Bash **)或基于 的解决方案find将很有用。

答案2

考虑到您的文件只有一次“成功运行”或没有,那么:

要找到匹配的文件,您可以执行以下操作:

grep -l "successful run" *.out > err.txt

找到并删除它们:

grep -l "successful run" *.out | xargs rm

要查找不匹配的文件,请执行以下操作:

grep -vl "successful run" *.out > ok.txt

找到并删除它们:

grep -vl "successful run" *.out | xargs rm

这些标志的含义是:

-l lists the files with matches
-v/--invert-match inverts the matching logic

相关内容