删除不包含特定字符串的文件

时间:2012-07-01 07:53:25

标签: linux bash sed grep

我想找到不包含特定字符串的文件(在目录及其子目录中)并删除这些文件。我怎么能这样做?

6 个答案:

答案 0 :(得分:9)

以下内容可行:

find . -type f -print0 | xargs --null grep -Z -L 'my string' | xargs --null rm

这将首先使用find来打印当前目录和所有子目录中所有文件的名称。这些名称使用空终止符而不是通常的换行符分隔符打印(尝试将输出汇总到od -c以查看-print0参数的效果。

然后--null参数xargs告诉它接受以空值终止的输入。然后,xargs会在文件名列表中调用grep

-Z的{​​{1}}参数与grep的{​​{1}}参数类似,因此grep将打印出以null结尾的结果(这就是为什么最后调用-print0也需要find选项。 xargs的{​​{1}}参数会导致--null在其命令行上打印这些文件的文件名(-L已添加)匹配正则表达式:

  

我的字符串

如果您想要没有正则表达式魔法的简单匹配,请添加grep选项。如果你想要更强大的正则表达式,那么给出一个grep参数。使用单引号而不是双引号是一个好习惯,因为这可以保护您免受任何应用于字符串的shell魔法(例如变量替换)

最后再次致电xargs,以摆脱之前通话中找到的所有文件。

直接从带有-F参数的-E命令调用xargs的问题是grep然后每个文件调用一次,而不是一整批调用find文件为-exec。如果您有大量文件,这会更快。也不要试图做这样的事情:

grep

最好将它传递给xargs,因为它知道最大命令行限制,并且每次都会使用尽可能多的参数多次调用rm $(some command that produces lots of filenames)

请注意,此解决方案可以更简单,无需处理包含空格和新行的文件。

可选地

xargs

也会起作用(并且更短)。 rm的{​​{1}}参数使其读取目录中的所有文件并递归地下降到任何子目录中。如果您还想对文件进行其他测试(例如年龄或权限),请使用grep -r -L -Z 'my string' . | xargs --null rm 方法。

请注意,任何带有单个dash引入程序的单字母参数都可以组合在一起(例如-r)。但请注意,grep不使用相同的约定,并且使用单个破折号引入了多字母参数。这是出于历史原因,并且从未修复过,因为它会破坏太多的脚本。

答案 1 :(得分:5)

GNU grep和bash。

grep -rLZ "$str" . | while IFS= read -rd '' x; do rm "$x"; done

如果需要可移植性,请使用find解决方案。这稍快一些。

答案 2 :(得分:3)

编辑:这就是不应该这样做的方式!原因是here。感谢@ormaaj指出它!

find . -type f | grep -v "exclude string" | xargs rm

注意:grep模式将与当前目录中的完整文件路径匹配(请参阅find . -type f输出)

答案 3 :(得分:1)

我可以想办法解决这个问题。这是一个:find和grep生成一个没有匹配的文件列表,然后是xargs rm。

find yourdir -type f -exec grep -F -L 'yourstring' '{}' + | xargs -d '\n' rm

这假定GNU工具(grep -L和xargs -d是非可移植的),当然没有带有换行符的文件名。它的优点是每个文件不运行grep和rm一次,所以它会相当快。我建议用“echo”代替“rm”进行测试,以确保在释放破坏之前选择正确的文件。

答案 4 :(得分:0)

一种可能性是

find . -type f '!' -exec grep -q "my string" {} \; -exec echo rm {} \;

如果此预览看起来正确,您可以删除echo

答案 5 :(得分:0)

要删除不包含特定字符串的文件,请执行以下操作:

重击:

要使用它们,请启用extglob shell选项,如下所示:

shopt -s extglob

然后删除所有没有字符串“ fix”的文件:

rm !(*fix*)

如果您不想删除所有没有名称“ fix”和“ class”的文件:

rm !(*fix*|*class*)

Zsh:

要使用它们,请启用扩展的glob zsh shell选项,如下所示:

setopt extended_glob

删除所有没有字符串的文件,在此示例中为“ fix”:

rm -- ^*fix*

如果您不想删除所有没有名称“ fix”和“ class”的文件:

rm -- ^(*fix*|*class*)

可以将其用于扩展,您只需要更改正则表达式:( .zip),( .doc)等。

以下是来源:

https://www.tecmint.com/delete-all-files-in-directory-except-one-few-file-extensions/

https://codeday.me/es/qa/20190819/1296122.html