The following will work:
(以下将起作用:)
find . -type f -print0 | xargs --null grep -Z -L 'my string' | xargs --null rm
This will firstly use find to print the names of all the files in the current directory and any subdirectories.
(这将首先使用find来打印当前目录及其所有子目录中所有文件的名称。)
These names are printed with a null terminator rather than the usual newline separator (try piping the output to od -c
to see the effect of the -print0
argument. (这些名称使用空终止符而不是通常的换行符来打印(尝试将输出通过管道传递给od -c
以查看-print0
参数的效果。)
Then the --null
parameter to xargs
tells it to accept null-terminated inputs.
(然后, xargs
的--null
参数告诉它接受以null结尾的输入。)
xargs
will then call grep
on a list of filenames. (然后xargs
将在文件名列表上调用grep
。)
The -Z
argument to grep
works like the -print0
argument to find
, so grep will print out its results null-terminated (which is why the final call to xargs
needs a --null
option too).
(该-Z
参数grep
作品像-print0
参数find
,这样的grep会打印出它的结果空值终止的(这就是为什么到最后调用xargs
需要--null
选项也是如此)。)
The -L
argument to grep
causes grep
to print the filenames of those files on its command line (that xargs
has added) which don't match the regular expression: (grep
的-L
参数使grep
在其命令行( xargs
已添加)上打印与正则表达式不匹配的那些文件的文件名:)
my string
(我的弦)
If you want simple matching without regular expression magic then add the -F
option.
(如果您想要不带正则表达式魔术的简单匹配,请添加-F
选项。)
If you want more powerful regular expressions then give a -E
argument. (如果要使用更强大的正则表达式,请提供-E
参数。)
It's a good habit to use single quotes rather than double quotes as this protects you against any shell magic being applied to the string (such as variable substitution) (使用单引号而不是双引号是一个好习惯,因为这可以保护您避免将任何外壳魔术应用于字符串(例如变量替换))
Finally you call xargs
again to get rid of all the files that you've found with the previous calls.
(最后,您再次调用xargs
来摆脱在先前调用中找到的所有文件。)
The problem with calling grep
directly from the find
command with the -exec
argument is that grep
then gets invoked once per file rather than once for a whole batch of files as xargs
does.
(直接使用带有-exec
参数的find
命令从grep
调用grep
的问题是,然后每个文件调用一次grep
而不是像xargs
那样对整个文件调用一次。)
This is much faster if you have lots of files. (这是更快 ,如果你有大量的文件。)
Also don't be tempted to do stuff like: (也不要试图做类似的事情:)
rm $(some command that produces lots of filenames)
It's always better to pass it to xargs
as this knows the maximum command-line limits and will call rm
multiple times each time with as many arguments as it can.
(最好将它传递给xargs
因为它知道最大的命令行限制,并且每次调用rm
使用尽可能多的参数多次。)
Note that this solution would have been simpler without the need to cope with files containing white space and new lines.
(请注意,此解决方案本来会更简单,而无需处理包含空格和换行符的文件。)
Alternatively
(或者)
grep -r -L -Z 'my string' . | xargs --null rm
will work too (and is shorter).
(也会工作(并且更短)。)
The -r
argument to grep
causes it to read all files in the directory and recursively descend into any subdirectories). (grep
的-r
参数使它读取目录中的所有文件,然后递归地进入任何子目录)。)
Use the find ...
approach if you want to do some other tests on the files as well (such as age or permissions). (如果您还想对文件进行其他测试(例如使用期限或权限),请使用find ...
方法。)
Note that any of the single letter arguments, with a single dash introducer, can be grouped together (for instance as -rLZ
).
(请注意,任何带有单个破折号-rLZ
的单个字母参数都可以组合在一起(例如,作为-rLZ
)。)
But note also that find
does not use the same conventions and has multi-letter arguments introduced with a single dash. (但也请注意, find
不使用相同的约定,并且用单破折号引入了多个字母的参数。)
This is for historical reasons and hasn't ever been fixed because it would have broken too many scripts. (这是出于历史原因,从未修复过,因为它会破坏太多脚本。)