Zsh GNU并行中包含空格和特殊字符的转义变量

Zsh GNU并行中包含空格和特殊字符的转义变量,zsh,gnu-parallel,Zsh,Gnu Parallel,我尝试将PDF文件的优化并行化。(我在Mac电脑上) 只要路径中没有空格或特殊字符,一切正常。mv命令失败: usage: mv [-f | -i | -n] [-v] source target mv [-f | -i | -n] [-v] source ... directory 我尝试了以下有助于目录路径的方法,但是以同样的方式包装$(basename{})不起作用 mv {.}_optimized.pdf '\"$DOCUMENT\"'_split/$

我尝试将PDF文件的优化并行化。(我在Mac电脑上)

只要路径中没有空格或特殊字符,一切正常。
mv
命令失败:

usage: mv [-f | -i | -n] [-v] source target
       mv [-f | -i | -n] [-v] source ... directory
我尝试了以下有助于目录路径的方法,但是以同样的方式包装
$(basename{})
不起作用

mv {.}_optimized.pdf '\"$DOCUMENT\"'_split/$(basename {})

我突然想到,有一种可能性比摆弄所有的引用要容易得多:如果你把
DOCUMENT
作为一个环境变量,你可以让all通过
parallel
调用的shell进行扩展:

export DOCUMENT
只是因为我不知道shell parallel使用的是什么,所以我不希望它运行zsh,而是希望它能够准备好参数,这样即使在POSIX shell中也能工作:

... parallel -0 -j+0 '/usr/local/bin/ps2pdf {} {.}_optimized.pdf && mv {.}_optimized.pdf "$DOCUMENT_split/$(basename "{}")";'

通过这种方式,parallel执行的shell可以准确地看到两个单引号之间的内容。这意味着您甚至可以通过将适当的值替换为DOCUMENT和{}来测试这种方法。

gnupallel的替换字符串将正确引用结果字符串。这意味着即使在疯狂的文件名上使用它也是安全的:

touch "  Spacey  My brother's 12\" records.txt"
find . -print0 | parallel -0 echo {} {.}
此保证不适用于变量,尤其不适用于在命令模板中执行的命令的输出

# This does not do what you expect
DOCUMENT="It's  \"two\"  spaces"
find . -print0 | parallel -0 echo $DOCUMENT $(basename {})
您可以使用替换字符串{.},而不是
basename
<代码>$DOCUMENT每次都很难做到正确:

DOCUMENT="It's  \"two\"  spaces"
export DOCUMENT
find . -print0 | parallel -0 echo '"$DOCUMENT"' {.}
通常,创建bash函数并调用该函数更容易:

doit() {
  f="$1"
  echo "$DOCUMENT" "$(basename "$f")"
}
export -f doit
export DOCUMENT
find . -print0 | parallel -0 doit

(PS:
-j+0
多年来一直是默认值)。

您正在单引号内将参数传递给
parallel
,这意味着
$DOCUMENT
不会展开。顺便说一句,我不知道并行应该如何工作,但我也会验证哪个shell用于运行并行命令。如果我像这样传递它,
'..mv{.}\u optimized.pdf'\“$DOCUMENT\'''''u split/$(basename{})
它适用于
$DOCUMENT
,但不适用于
$(basename{})
,当然不适用,因为现在您有了
$(basename)
在单引号内:-ddddd即使这样,它也不起作用。
“…mv{.}\u optimized.pdf”\“$DOCUMENT\”““\u split/”$(basename{})”
不要忘记,您正在一起构建一个字符串,并行将被进一步处理。最有可能的是,并行本身也需要在字符串的各个部分加上合适的引号。我将首先测试此处生成的字符串,然后提供缺少的引号。当我将
$DOCUMENT
用额外的双引号括起来时,这几乎可以起作用,但是不幸的是,它在文件名后面附加了一个
'
。我这样测试它:
parallel-0-j+0'echo$(basename“{}”);
这是有效的:
parallel-0-j+0'/usr/local/bin/ps2pdf{}{}{.\u optimized.pdf&&mv optimized.pdf“$DOCUMENT”\u split$(basename{});
doit() {
  f="$1"
  echo "$DOCUMENT" "$(basename "$f")"
}
export -f doit
export DOCUMENT
find . -print0 | parallel -0 doit