xargs 与 rm + 文件名包含空格

xargs 与 rm + 文件名包含空格

我正在编写一个简单的程序来删除所有获取的文件。文件可以包含空格,因此我添加了引号,如下所示

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非常清楚如何将带有空格(或换行符或其他任何内容)的路径名传递给命名实用程序。

相关内容