在 find 命令中使用空格时出现问题

在 find 命令中使用空格时出现问题

我试图在每个不包含任何子目录的目录中放置一个包含目录内容的 zip 文件。

如果目录名和/或文件名中没有空格,则以下命令有效,但如果有空格则失败:

find pictures/ -type d -links 2 -execdir sh -c "pwd; echo '{}'; zip -v '{}/{}.zip' '{}/*' -x \*.zip -x \*.id" \;

我不明白为什么它会失败,因为我像往常一样引用了“{}”。还尝试了“{}”。换句话说,它应该使用 A/B/C/* 的内容创建 A/B/C/C.zip。如果“C”中有空格,我得到:

zip warning: name not matched: ./C/*
zip error: Nothing to do! (./C/./C.zip)

答案1

对于您的 版本find{}字符串中的 会被文件名替换。用作字符串的一部分几乎总是错误的{},因为文件名就是这样插入的。这里,文件名用作 shell 脚本片段。如果有一个名为的目录a'$(touch wibble)',那么您的命令将执行 shell 代码

pwd; echo 'a'$(touch wibble)''; zip -v 'a'$(touch wibble)'/a'$(touch wibble)'.zip' 'a'$(touch wibble)'/*' -x \*.zip -x \*.id"`

请注意它如何执行命令touch wibble(四次)。

您需要将文件名作为参数传递给 shell 代码片段。这是可靠地使用find -execfind -execdir调用 shell 的唯一方法(除非文件名被限制为没有特殊字符,包括空格)。之后的第一个参数sh -c SCRIPT可以从脚本中访问为"$0"

此外,zip要压缩的文件列表中不接受通配符,因此通配符必须不加引号,以便由 shell 扩展。

find pictures/ -type d -links 2 -execdir sh -c 'pwd; echo "$0"; zip -v "$0/$0.zip" "$0/"* -x \*.zip -x \*.id' {} \;

答案2

像这样改变它:

find pictures -type d -links 2 -execdir \
    sh -c 'pwd; echo "$1"; zip -vr "$1/$1.zip" "$1" -x \*.zip -x \*.id' sh {} \;

相关内容