Lov*_*ths 3 linux shell find xargs
我正在编写一个简单的程序来删除所有获取的文件。文件可以包含空格,所以我添加了引号,如下所示
find -name "*.scala" | xargs -d "\n" -I {} rm \"{}\"
Run Code Online (Sandbox Code Playgroud)
以上失败并出现错误:无法删除,没有这样的文件或目录。但是如果我列出相同的文件,它们就在那里。此外,如果我在下面执行并使用 bash 执行它;有用
find -name "*.scala" | xargs -d "\n" -I {} echo rm \"{}\" | bash
Run Code Online (Sandbox Code Playgroud)
有人可以解释为什么第一种情况不起作用吗?
xargs -d "\n" -I {} rm \"{}\"
Run Code Online (Sandbox Code Playgroud)
这假设 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
Run Code Online (Sandbox Code Playgroud)
当您将生成的命令通过管道传输到时,它会起作用,bash因为bash会删除引号。
如果您一开始就没有付出额外的努力来添加引号,它也可能会起作用:
xargs -d "\n" -I {} rm {}
Run Code Online (Sandbox Code Playgroud)
要正确删除文件,请使用
find . -type f -name '*.scala' -delete
Run Code Online (Sandbox Code Playgroud)
或者,如果您仍想使用xargs:
find . -type f -name '*.scala' -print0 | xargs -0 rm
Run Code Online (Sandbox Code Playgroud)
它将find和之间的路径名xargs作为空分隔列表传递。Nul ( \0) 是唯一不允许出现在 Unix 系统路径名中的字符。文件名也可以不包含/,但允许换行。
第三种选择是rm直接从调用find:
find . -type f -name '*.scala' -exec rm {} +
Run Code Online (Sandbox Code Playgroud)
请注意,{}不需要(也不应该)引用它,因为它find非常清楚如何将带有空格(或换行符或其他任何内容)的路径名传递给命名实用程序。