shell 的 ifdef 样式条件包含

shell 的 ifdef 样式条件包含

考虑以下脚本。

#!/bin/sh                                                                                                                                                   

echo "" | ps2pdf -sPAPERSIZE=a4 - blank.pdf
cp blank.pdf blank2.pdf

pdftk \
    A=blank.pdf `#first file` \
    B=blank2.pdf `#second file` \
    cat A B \
    output b.pdf

但假设我想要一个变体:

#!/bin/sh                                                                                                                                                   

echo "" | ps2pdf -sPAPERSIZE=a4 - newblank.pdf
cp newblank.pdf newblank2.pdf

pdftk \
    A=newblank.pdf `#first file revised` \
    B=newblank2.pdf `#second file revised` \
    cat A B \
    output b.pdf

现在,假设我希望他们在一起。我可以

#!/bin/sh                                                                                                                                                   

echo "" | ps2pdf -sPAPERSIZE=a4 - blank.pdf
cp blank.pdf blank2.pdf
cp blank.pdf newblank.pdf
cp blank.pdf newblank2.pdf

pdftk \
    A=blank.pdf `#first file` \
    `#A=newblank.pdf` `#first file revised` \
    B=blank2.pdf `#second file` \
    `#B=newblank2.pdf` `#second file revised` \
    cat A B \
    output b.pdf

但如果我想在版本之间来回切换,我必须注释和取消注释。有没有某种方法可以进行条件包含,以便我可以(比如说)以 C 宏的风格根据变量是否定义来获得一个版本#ifdef

如果有一个可移植的 shell 解决方案就好了,但如果没有,一个 bash 特定的解决方案也可以。

最后,我在此示例中仅使用两个文件 ( blank.pdf. blank2.pdf),但我需要一个可处理任意数量文件的解决方案。此外,最好将每个文件的旧版本和新版本放在一起以进行比较。此外,某些文件在原始版本和新版本中可能是相同的,因此在这种情况下最好不必重复这些文件。

答案1

您提供的版本之间的区别只是文件名/参数不同。

用类似“”的结构来区分或多或少相同的代码的变体ifdef通常不是最好的方法,因为它会导致难以维护和重复的代码。

在您的示例中,您可以使用 shell 变量(和一个小子if ... ; then句)在两个变体之间切换:

 #call the script with -2 to switch to the second version.
 if [ "$1" = "-2" ]; then
           firstfile="newblank.pdf"
           secondfile="newblank2.pdf"   
 else
           firstfile="blank.pdf"
           secondfile="blank2.pdf"   
fi

echo "" | ps2pdf -sPAPERSIZE=a4 - "$infile"
cp "$firstfile" "$secondfile"

pdftk \
    "A=$firstfile" `#first file` \
    "B=$secondfile" `#second file` \
    cat A B \
    output b.pdf

如果您想多次调用相同的代码,只需稍作更改,您可能会考虑定义functions并用不同的参数调用它们。

答案2

要获取参数作为值定义的条件,您只需有条件地扩展该值即可。

unset var
echo  ${var+" nothing because this is unset "}
var=
echo  ${var-" nothing because the value is null but the var is set "}
var=value
echo  ${var:+" this will expand    -    to my optionally provided word "} 

:+表格将扩展为单词当一个变量既被设置又不为空时。:-将扩展到单词当它未设置或为 null 时 - 否则它会扩展为其值。不带冒号的形式[+-]类似,但删除了空值的任何条件,并且仅测试是否设置了参数。

如果你有一个像这样的参数列表:

pdftk \
    arg arg ${first+"`#first file ${rev+revised}`"} \
    ${blank+"blankfile"} ${second+"`#second file ${rev+revised}`"}

...你也许可以让它发挥作用...

echo "" | ps2pdf -sPAPERSIZE=a4 - "${pre+${age:=new}}blank.pdf"
cp "${pre+$age}blank.pdf" "${pre+$age}blank2.pdf"

pdftk \
    "A=${pre+$age}blank.pdf" "`#first file${rev:+ revised: $rev}`" \
    "B=${pre+$age}blank2.pdf" "`#second file${rev:+ revised: $rev}`" \
    cat A B \
    output b.pdf

因为它们是嵌套的,所以您可以选择在一个值中扩展一个值。所以...

pre=+ rev=$(date) age=old your_script

...结果会与...有很大不同

unset pre rev age; your_script

相关内容