如何解决GNU并行中包含空格和特殊字符的转义变量
我尝试并行优化 PDF 文件。 (我用的是 Mac)
#!/bin/zsh
TMP_DIR=$(mktemp -d)
DOCUMENT="/some/path/with/sp aces/and/üö chars.pdf"
mkdir "$DOCUMENT"_split
#split pdf into single pages
/usr/local/bin/pdfseparate "$DOCUMENT" "$TMP_DIR/${$(basename $DOCUMENT)%.pdf}_%d.pdf"
find "$TMP_DIR" -mindepth 1 -maxdepth 1 -name "*.pdf" ! -print0 | parallel -0 -j+0 '/usr/local/bin/ps2pdf {} {.}_optimized.pdf && mv {.}_optimized.pdf $DOCUMENT_split/$(basename {});'
一切正常,只要路径中没有空格或特殊字符。 mv
命令失败:
usage: mv [-f | -i | -n] [-v] source target
mv [-f | -i | -n] [-v] source ... directory
我尝试了以下有助于目录路径的方法,但以相同的方式包装 $(basename {})
不起作用。
mv {.}_optimized.pdf '\"$DOCUMENT\"'_split/$(basename {})
解决方法
GNU Parallel 的替换字符串将正确引用结果字符串。这意味着即使是疯狂的文件名也可以安全使用:
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
多年来一直是默认设置)。
我突然想到,有比摆弄所有引用更容易的可能性:如果您将 DOCUMENT
设为环境变量,您可以让 all 展开parallel
调用的 shell:
export DOCUMENT
只是因为我不知道 parallel 正在使用什么 shell,我不会指望它运行 zsh,并且会准备参数以便它即使在 POSIX shell 中也能工作:
... parallel -0 -j+0 '/usr/local/bin/ps2pdf {} {.}_optimized.pdf && mv {.}_optimized.pdf "$DOCUMENT_split/$(basename "{}")";'
这样,parallel 执行的 shell 就能准确地看到两个单引号之间的内容。这意味着您甚至可以通过将合适的值替换为 DOCUMENT 和 {} 来测试该方法。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。