我正在编写一个简单的程序来删除所有获取的文件。文件可以包含空格,因此我添加了引号,如下所示
find -name "*.scala" | xargs -d "\n" -I {} rm \"{}\"
上面的操作失败并出现错误:无法删除,没有这样的文件或目录。但如果我列出相同的文件,它们就在那里。另外,如果我执行以下操作并使用 bash 来执行它;有用
find -name "*.scala" | xargs -d "\n" -I {} echo rm \"{}\" | bash
有人可以解释一下为什么第一种情况不起作用吗?
答案1
xargs -d "\n" -I {} rm \"{}\"
这假设 GNU coreutils 版本xargs
支持-d
指定分隔符的选项。
这不会与您的find
命令一起使用,因为它会向 . 找到的路径名添加双引号find
。这意味着对 的./somedir/file.scala
调用不是rm
通过文字路径名完成的"./somedir/file.scala"
。
例子:
$ touch hello
$ touch '"hello"'
$ ls
"hello" hello
$ echo hello | xargs -d "\n" -I {} rm \"{}\"
$ ls
hello
当您将生成的命令通过管道传输到时它会起作用,bash
因为bash
会删除引号。
如果您不首先付出额外的努力来添加引号,它也可能会起作用:
xargs -d "\n" -I {} rm {}
要正确删除文件,请使用
find . -type f -name '*.scala' -delete
或者,如果您仍然想使用xargs
:
find . -type f -name '*.scala' -print0 | xargs -0 rm
find
它将和之间的路径名xargs
作为空分隔列表传递。空 ( \0
) 是仅有的Unix 系统上路径名中不允许使用的字符。另外,文件名不能包含/
,但允许换行。
第三种选择是rm
直接从以下位置调用find
:
find . -type f -name '*.scala' -exec rm {} +
请注意,{}
不需要(也不应该)引用,因为find
非常清楚如何将带有空格(或换行符或其他任何内容)的路径名传递给命名实用程序。