我想删除所有包含字符串的文件foo
。如何在 Linux 中使用 bash 执行此操作?
答案1
这是一个安全的方法:
grep -lrIZ foo . | xargs -0 rm -f --
-l
打印与搜索模式匹配的文件的文件名。-r
foo
在给定目录中对模式执行递归搜索.
。如果此操作无效,请尝试-R
。-I
(大写i
)导致跳过 PDF 等二进制文件。-Z
确保文件名以零(即,空)结尾,以便包含空格的名称不会被错误地解释(即,被解释为多个名称而不是一个)。xargs -0
将文件名从 提供给grep
,rm -f
用零(nul)字节分隔单词(记住-Z
的选项grep
)。--
经常被遗忘,但标记选项的结束并允许删除名称以 开头的文件非常重要-
。
如果您想查看即将删除的文件,只需删除该| xargs -0 rm -f --
部分,然后关闭Z
选项grep
。
另一位用户建议了类似以下内容你不应该跑因为它不安全:
files=`grep foo * | cut -d: -f1`
rm -f $files # unsafe, do not run it!
如果我有ImportantStuff
不想删除的文件,并且obsolete ImportantStuff
包含foo
,那么我就会丢失ImportantStuff
(并且不是 obsolete ImportantStuff
!),因为$files
在解释时会在空格处断开。以这种方式将文件名列表放入标量 shell 变量中很危险。
答案2
$ find -type f -exec grep -q "foo" {} \; -exec echo rm -- {} \;
这将递归搜索包含的文件。仅当第一个成功退出时(即如果匹配)才会运行foo
第二个。如果输出看起来正确,则运行 dryrun 并删除。-exec
exec
grep
echo
或者
$ find -type f -exec grep -q "foo" {} \; -print
和
$ find -type f -exec grep -q "foo" {} \; -delete
按照 Lekensteyn 的建议。
答案3
我会按照阿德里安说的做,
但是我会在 foo 周围添加单词边界,以免意外删除包含“food”的文件(除非您想要删除所有包含 food 的文件。)
$ find -type f -exec grep -q "\<foo\>" {} \; -delete
实际上,我会在删除之前重定向输出,以便我可以在删除之前进行检查:
$ find -type f -exec grep -q "\<foo\>" > /tmp/list_of_files_to_delete