Bash中转义文件名中的空格,以及转义变量中的空格

4

我对Bash还比较陌生,所以这可能是一些微不足道的东西,但我就是不懂。我正在尝试转义文件名中的空格。看一下这个例子。请注意,这只是一个“工作示例” - 我知道用空白页面交替文件可能会更容易实现,但我关心的是空格。

#! /bin/sh

first=true
i=combined.pdf
o=combined2.pdf
for f in test/*.pdf
do
    if $first; then
        first=false
        ifile=\"$f\"
    else
        ifile=$i\ \"$f\"
    fi
    pdftk $ifile blank.pdf cat output $o
    t=$i
    i=$o
    o=$t
    break
done

假设我有一个名为`my file.pdf`(包含空格)的文件。我希望`ifile`变量包含字符串`combined.pdf "my file.pdf"`,以便pdftk能够将其用作两个文件参数——第一个是`combined.pdf`,第二个是`my file.pdf`。
我尝试过各种转义方式(是否需要首先转义引号等),但在执行pdftk时它仍会分割`my`和`file.pdf`。
编辑:澄清一下:我正在尝试将多个文件名(作为多个参数)传递给pdftk命令。我希望它能识别两个文件名之间的差异,但不要将一个文件名拆分成多个部分。

1
不想让您感到烦恼,但只需要谷歌两秒钟,我就找到了这个链接:http://www.lornajane.net/posts/2011/combining-pdf-files-with-pdftk - Adam Gent
这只是我的问题的“最小工作示例”。在附加文件之前,我还要做一些其他事情。 - Joost
啊,因为你需要在每个页面之间留出一个空白页。我没有注意到这一点。 - Adam Gent
你为什么变得这么复杂?使用两个变量: pdftk "$i" "$f" ... - glenn jackman
@AdamGent - 感谢您指向 lornajane.net/posts/2011/combining-pdf-files-with-pdftk - 我通过 xargs 的-J选项学到了新东西。 - jaygooby
2个回答

8
将多个参数放入单个变量中没有意义。相反,将它们放入数组中:
args=(combined.pdf "my file.pdf");

请注意,"my file.pdf" 用引号括起来以保留空格。
您可以像这样使用数组:
pdftk "${args[@]}" ...

这将向pdftk传递两个单独的参数。在"${args[@]}"中的引号是必需的,因为它们告诉shell将每个数组元素视为单独的“单词”(即使它们包含空格,也不会分割数组元素)。
顺便说一下,如果您使用像数组这样的bashism,请将shebang更改为:
#!/bin/bash

我非常确定,如果文件名中有空格,它将无法正常工作。我记得曾经做过类似的事情时遇到了问题。 - Adam Gent
这就是我应该从一开始就做的事情。尝试使用字符串来做这件事是无意义的。谢谢! - Joost
1
bash手册中关于数组的部分,@AdamGent可以看到:如果单词被双引号包含,${name[@]}会将name的每个元素扩展为一个单独的单词。换句话说,数组元素不会在空格上拆分。 - ThisSuitIsBlackNot
@ThisSuitIsBlackNot 我不记得确切的问题,但我认为这是文件名中换行符的问题。我不得不使用空分隔符,类似于find/xargs组合。 - Adam Gent
2
xargs 解析 find 命令的输出问题与引用空格以防止 shell 对其进行单词拆分的问题是不同的问题。 - chepner

1

尝试:

find test/*.pdf | xargs -I % pdftk % cat output all.pdf

正如我在评论其他答案时所说,xargs 是实现这一功能最有效的方式。
编辑:我没有看到你需要一个空白页,但我想你可以将上面的 find 管道传递给某个命令,在它们之间插入空白页(类似于列表->字符串连接)。我更喜欢这种方式,因为它更像函数式编程。

你没有转义空格。应该是 find test/*.pdf -print0 | xargs -0 -J % pdftk % cat output all.pdf - jaygooby

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接