【发布时间】:2012-07-02 01:59:52
【问题描述】:
我想查找不包含特定字符串的文件(在目录及其子目录中)并删除这些文件。我该怎么做?
【问题讨论】:
-
@SivaCharan 是的......从存在:)
-
删除我的意思是:删除
我想查找不包含特定字符串的文件(在目录及其子目录中)并删除这些文件。我该怎么做?
【问题讨论】:
以下将起作用:
find . -type f -print0 | xargs --null grep -Z -L 'my string' | xargs --null rm
这将首先使用 find 打印当前目录和任何子目录中所有文件的名称。这些名称使用空终止符而不是通常的换行符分隔符打印(尝试将输出通过管道传输到 od -c 以查看 -print0 参数的效果。
然后xargs 的--null 参数告诉它接受以空值结尾的输入。然后xargs 将在文件名列表上调用grep。
grep 的 -Z 参数与 find 的 -print0 参数的工作方式类似,因此 grep 将打印出以空值结尾的结果(这就是对 xargs 的最终调用需要 --null 的原因选项)。 -L 到 grep 的参数导致 grep 在其命令行上打印那些不与正则表达式匹配的文件的文件名(xargs 已添加): p>
我的字符串
如果您想要简单的匹配而不需要正则表达式魔法,那么添加-F 选项。如果您想要更强大的正则表达式,请提供-E 参数。使用单引号而不是双引号是一个好习惯,因为这可以保护您免受任何应用于字符串的 shell 魔法(例如变量替换)
最后你再次调用xargs 以删除你在之前调用中找到的所有文件。
使用-exec 参数直接从find 命令调用grep 的问题是grep 然后每个文件调用一次,而不是像xargs 那样为整批文件调用一次。如果您有很多文件,这会快得多。也不要试图做类似的事情:
rm $(some command that produces lots of filenames)
最好将它传递给xargs,因为它知道最大命令行限制,并且每次都会使用尽可能多的参数多次调用rm。
请注意,此解决方案会更简单,无需处理包含空格和新行的文件。
或者
grep -r -L -Z 'my string' . | xargs --null rm
也可以(而且更短)。 -r 参数 grep 导致它读取目录中的所有文件并递归地下降到任何子目录)。如果您还想对文件进行一些其他测试(例如年龄或权限),请使用 find ... 方法。
请注意,任何带有单个破折号介绍器的单字母参数都可以组合在一起(例如-rLZ)。但还要注意find 不使用相同的约定,并且使用单个破折号引入了多字母参数。这是出于历史原因,并且从未修复过,因为它会破坏太多脚本。
【讨论】:
grep -r -L -Z 'Astring' OR 'Bstring' OR 'Cstring' * | xargs --null rm这样的字符串列表?
xargs: illegal option -- -
GNU grep 和 bash。
grep -rLZ "$str" . | while IFS= read -rd '' x; do rm "$x"; done
如果需要可移植性,请使用find 解决方案。这稍微快一些。
【讨论】:
-r,它似乎别无选择,只能默认为文件,除非明确给出-。不过,. 可能是个好主意。已添加。
. 时,我已经删除了我的原始评论,你肯定已经看到了,但我也有点困惑,因为'man grep' 显示[FILE ...] for最后一个选项......但这绝对是这里发生的事情(即等待输入,没有.); GNU grep 2.5.4
2.12 在这里。 2.5.4 是我的仓库中可用的最旧的。
一种可能性是
find . -type f '!' -exec grep -q "my string" {} \; -exec echo rm {} \;
如果此预览的输出看起来正确,您可以删除 echo。
与-delete 等价的是
find . -type f '!' -exec grep -q "user_id" {} \; -delete
但是你没有得到很好的预览选项。
【讨论】:
echo。
NOT containing。出于这个原因,我给了-1,因为这个答案可能会毁了某人的生活。我也在标记。
! 添加到find 的参数以颠倒意义有多难?这不像任何人会盲目地复制答案而不试图理解它是做什么的。而echo rm 几乎不会毁掉任何人的生活。
我可以想出几种方法来解决这个问题。这里有一个: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”对其进行测试,以确保它在释放破坏之前选择正确的文件。
【讨论】:
-0 是唯一的方法。
删除不包含特定字符串的文件:
重击:
要使用它们,请启用 extglob shell 选项,如下所示:
shopt -s extglob
然后删除所有没有字符串“fix”的文件:
rm !(*fix*)
如果您不想删除所有没有名称“fix”和“class”的文件:
rm !(*fix*|*class*)
Zsh:
要使用它们,请启用扩展 glob zsh shell 选项,如下所示:
setopt extended_glob
删除所有没有字符串的文件,在本例中为“修复”:
rm -- ^*fix*
如果您不想删除所有没有名称“fix”和“class”的文件:
rm -- ^(*fix*|*class*)
可以将其用于扩展,您只需更改正则表达式: (.zip) 、 (.doc) 等
以下是来源:
https://www.tecmint.com/delete-all-files-in-directory-except-one-few-file-extensions/
【讨论】:
这对我有用,如果您可以删除目录,则可以删除 -f。
myString="keepThis"
for x in `find ./`
do if [[ -f $x && ! $x =~ $myString ]]
then rm $x
fi
done
【讨论】: