一个目录下有上千个数据文件(扩展名相同),如何删除那些包含特定参数语句的数据文件?
例如,如果我要删除包含该行的所有文件
Key = 0
我可以做类似的事情吗
grep -i "Key = 0" * | rm *
答案1
您可以在 shell 中使用以下命令。如果要搜索的模式是,这应该可以完成工作Key = 0
grep -lrIZ "Key = 0" . | xargs -0 rm -f --
通用命令:
grep -lrIZ "<Pattern to be searched in the file>" . | xargs -0 rm -f --
答案2
grep
使用+的管道的主要问题rm
是rm
不从其标准输入流中读取,这意味着它不会从grep
管道左侧的命令中读取任何内容。
相反,rm *
管道右侧的 会忽略所有输入并rm
在当前目录中的每个可见文件名上执行。
rm
忽略不读取其标准输入的问题,您的grep
命令有两个主要问题:
- 它输出与文件名匹配的行。这没有用,
rm
因为我们需要知道仅有的我们要删除的文件的文件名。 - 它匹配
Key = 0
为子串,这意味着它也匹配Crypto Key = 0x01
等。
find . -type f -exec grep -q -F -x 'Key = 0' {} \; -exec rm -f {} +
或者,对于 GNU find
(和其他一些),
find . -type f -exec grep -q -F -x 'Key = 0' {} \; -delete
这两者都会在当前目录或以下目录中查找常规文件,并且对于每个找到的文件,它将执行grep -q -F -x 'Key = 0'
.该grep
命令将返回退出状态,表明文件中是否有一行确切地 Key = 0
(没有别的)。
如果找到这样的行,第二个find
命令将使用其谓词删除该文件。-delete
第一个find
命令将收集包含该行的文件的路径名,然后rm -f
批量运行这些文件。
使用的标志grep
是
-q
,安静运行。该实用程序不输出匹配行,但会在第一次匹配后成功退出,或者如果文件不包含匹配项,则退出状态为非零。-F
,用于固定字符串匹配。我们匹配的是字符串,而不是正则表达式。-x
,仅查找全行匹配项。这与使用锚定到行的开头和结尾的正则表达式具有相同的效果。
我没有在这里使用-i
with grep
,因为这也会删除包含诸如 等行的文件KEY = 0
,kEY = 0
并且您对这些情况变化只字未提。
您是否希望find
命令被限制为特定的文件名后缀,例如,然后在执行 之前在命令中.ext
使用。例如:-name '*.ext'
find
grep
find . -name '*.ext' -type f -exec grep -q -F -x 'Key = 0' {} \; -exec rm -f {} +