bash:传递几个包含文件名的空格

bash:传递几个包含文件名的空格

在 bash 脚本中,我将 PDF 逐页光栅化为单个文件,最后生成的单个 PNG 再次合并到 PDF 中,如下所示:

convert -monitor /path/to/1.png /path/to/2.png /path/to/3.png ... output.pdf

脚本仍然存在的唯一问题是无法正确处理带有空格的文件。以下是我尝试过的一些事情:

newfile=$(sed -r -e 's| |\\ |g' <<< "$tmppath$curr.png")
echo "DEBUG: newfiles : $newfiles"
filearray[$curr-1]="$newfiles"
echo "DEBUG: filearray: ${filearray[*]}"

这产生(每页/文件):

DEBUG: newfiles : /tmp/pngpdf/file\ with\ spaces/1.png
DEBUG: filearray: /tmp/pngpdf/file\ with\ spaces/1.png

后来,我有两条调试消息

echo "DEBUG: filearray: ${filearray[*]}"
echo "DEBUG:            ${filearray[0]}, ${filearray[1]}, ${filearray[2]}, ..."

查看filearray多个文件/页面的外观:

DEBUG: filearray: /tmp/pngpdf/file\ with\ spaces/1.png /tmp/pngpdf/file\ with\ spaces/2.png /tmp/pngpdf/file\ with\ spaces/3.png /tmp/pngpdf/file\ with\ spaces/4.png /tmp/pngpdf/file\ with\ spaces/5.png
DEBUG:            /tmp/pngpdf/file\ with\ spaces/1.png, /tmp/pngpdf/file\ with\ spaces/2.png, /tmp/pngpdf/file\ with\ spaces/3.png, ...

我可以清楚地看到以下内容:

  1. 对于每个文件,只有一个数组元素。
  2. 每个空格前面都有一个\.

我首先将整个命令放入一个变量中,看看会执行什么:

execcmd="convert -monitor ${filearray[@]} output.pdf"

一个例子可能看起来像这样:

convert -monitor /tmp/pngpdf/file\ with\ spaces/1.png /tmp/pngpdf/file\ with\ spaces/2.png /tmp/pngpdf/file\ with\ spaces/3.png /tmp/pngpdf/file\ with\ spaces/4.png /tmp/pngpdf/file\ with\ spaces/5.png output.pdf

但是使用$execcmdConvert 执行它会向我抛出许多错误:

convert.im6: unable to open image `/tmp/pngpdf/file\': No such file or directory @ error/blob.c/OpenBlob/2638.
convert.im6: no decode delegate for this image format `/tmp/pngpdf/file\' @ error/constitute.c/ReadImage/544.
convert.im6: unable to open image `with\': No such file or directory @ error/blob.c/OpenBlob/2638.
convert.im6: no decode delegate for this image format `with\' @ error/constitute.c/ReadImage/544.
convert.im6: unable to open image `spaces/1.png': No such file or directory @ error/blob.c/OpenBlob/2638.
convert.im6: unable to open file `spaces/1.png' @ error/png.c/ReadPNGImage/3667.
convert.im6: unable to open image `/tmp/pngpdf/file\': No such file or directory @ error/blob.c/OpenBlob/2638.
convert.im6: no decode delegate for this image format `/tmp/pngpdf/file\' @ error/constitute.c/ReadImage/544.
convert.im6: unable to open image `with\': No such file or directory @ error/blob.c/OpenBlob/2638.
convert.im6: no decode delegate for this image format `with\' @ error/constitute.c/ReadImage/544.
convert.im6: unable to open image `spaces/2.png': No such file or directory @ error/blob.c/OpenBlob/2638.
convert.im6: unable to open file `spaces/2.png' @ error/png.c/ReadPNGImage/3667.
convert.im6: unable to open image `/tmp/pngpdf/file\': No such file or directory @ error/blob.c/OpenBlob/2638.
convert.im6: no decode delegate for this image format `/tmp/pngpdf/file\' @ error/constitute.c/ReadImage/544.
convert.im6: unable to open image `with\': No such file or directory @ error/blob.c/OpenBlob/2638.
convert.im6: no decode delegate for this image format `with\' @ error/constitute.c/ReadImage/544.
convert.im6: unable to open image `spaces/3.png': No such file or directory @ error/blob.c/OpenBlob/2638.
convert.im6: unable to open file `spaces/3.png' @ error/png.c/ReadPNGImage/3667.
convert.im6: unable to open image `/tmp/pngpdf/file\': No such file or directory @ error/blob.c/OpenBlob/2638.
convert.im6: no decode delegate for this image format `/tmp/pngpdf/file\' @ error/constitute.c/ReadImage/544.
convert.im6: unable to open image `with\': No such file or directory @ error/blob.c/OpenBlob/2638.
convert.im6: no decode delegate for this image format `with\' @ error/constitute.c/ReadImage/544.
convert.im6: unable to open image `spaces/4.png': No such file or directory @ error/blob.c/OpenBlob/2638.
convert.im6: unable to open file `spaces/4.png' @ error/png.c/ReadPNGImage/3667.
convert.im6: unable to open image `/tmp/pngpdf/file\': No such file or directory @ error/blob.c/OpenBlob/2638.
convert.im6: no decode delegate for this image format `/tmp/pngpdf/file\' @ error/constitute.c/ReadImage/544.
convert.im6: unable to open image `with\': No such file or directory @ error/blob.c/OpenBlob/2638.
convert.im6: no decode delegate for this image format `with\' @ error/constitute.c/ReadImage/544.
convert.im6: unable to open image `spaces/5.png': No such file or directory @ error/blob.c/OpenBlob/2638.
convert.im6: unable to open file `spaces/5.png' @ error/png.c/ReadPNGImage/3667.
convert.im6: no images defined `output.pdf' @ error/convert.c/ConvertImageCommand/3044.

显然,它无法正确识别我想要做什么。反斜杠本身被转义,因此,空格重新获得了它们的参数界定能力。当直接将该命令放入 bash 时,它运行顺利(如预期):

$ convert -monitor /tmp/pngpdf/file\ with\ spaces/1.png /tmp/pngpdf/file\ with\ spaces/2.png /tmp/pngpdf/file\ with\ spaces/3.png /tmp/pngpdf/file\ with\ spaces/4.png /tmp/pngpdf/file\ with\ spaces/5.png output.pdf
Load/Image//tmp/pngpdf/file with spaces[1.png]: 584 of 585, 100% complete
Load/Image//tmp/pngpdf/file with spaces[2.png]: 584 of 585, 100% complete
Load/Image//tmp/pngpdf/file with spaces[3.png]: 584 of 585, 100% complete
Load/Image//tmp/pngpdf/file with spaces[4.png]: 584 of 585, 100% complete
Load/Image//tmp/pngpdf/file with spaces[5.png]: 584 of 585, 100% complete
Mogrify/Image//tmp/pngpdf/file with spaces[5.png]: 4 of 5, 100% complete
resize image[output.pdf]: 180 of 181, 100% complete
resize image[output.pdf]: 180 of 181, 100% complete
resize image[output.pdf]: 180 of 181, 100% complete
resize image[output.pdf]: 180 of 181, 100% complete

这让我非常困惑,我不知道如何解决这个问题。我也尝试保存 filearray 中引用的单个文件名,但没有成功DEBUG: filearray: "/tmp/pngpdf/file with spaces/1.png" "/tmp/pngpdf/file with spaces/2.png" "/tmp/pngpdf/file with spaces/3.png" "/tmp/pngpdf/file with spaces/4.png" "/tmp/pngpdf/file with spaces/5.png"。 bash 可能也会转义这些特殊字符。我确信这一定与 bash 的工作原理有关,但似乎我的理解还不够好,无法自己解决这个问题。因此,如果有人能够启发我,我会非常高兴。 :)

PS:我一直在几个地方寻找我的问题的答案(文件名包含空格的 Shell 脚本问题,使用生成的文件名列表作为参数列表 - 带空格,循环遍历名称中带有空格的文件?,Bash 脚本和其中包含空格的文件,为什么我的 shell 脚本会因为空格或其他特殊字符而卡住?,文件名中存在空格的脚本出现问题)。不幸的是,我无法在那里找到我的问题的答案。也许已经太晚了;)

答案1

execcmd="convert -monitor ${filearray[@]} 输出.pdf"

但是用$execcmdConvert 执行它会给我带来很多错误

不要调用$execcmd,因为它已经失去了文件名和文件名的空格分隔部分之间的区别。相反,使用带引号的参数执行命令本身:

    convert -monitor "${filearray[@]}" output.pdf

相关内容