在Unix shell脚本中转义花括号

14

我有一个字符串:

{2013/05/01},{2013/05/02},{2013/05/03}

我想在开头添加 { ,并在结尾添加 } 。输出应该为:

{{2013/05/01},{2013/05/02},{2013/05/03}}

然而,当我在 shell 脚本中将大括号连接到字符串的开头和结尾时,输出如下所示:

{2013/05/01} {2013/05/02} {2013/05/03}

为什么会发生这种情况?我该如何达到我的目标?我相信这有一个简单的解决方案,但我是一个Unix新手,因此希望得到一些帮助。

测试脚本:

#!/usr/bin/ksh 
valid_data_range="{2013/05/01},{2013/05/02},{2013/05/03}"
finalDates="{"$valid_data_range"}"
print $finalDates
3个回答

5
问题在于,当大括号列表放在引号外面时,shell 会执行大括号扩展(bash 手册,但是ksh 也类似)。由于“引号外部”很重要,所以它还告诉您如何避免问题:在打印时将字符串括在引号中。
#!/usr/bin/ksh 
valid_data_range="{2013/05/01},{2013/05/02},{2013/05/03}"
finalDates="{$valid_data_range}"
print "$finalDates"

print 命令是特定于 ksh 的,并不存在于 bash 中。赋值行中的更改更多地是为了美观而非功能性。)
此外,在中不会发生花括号扩展;只有在直接编写花括号时才会发生。这是一个双语脚本(使用 kshbash)。
valid_data_range="{2013/05/01},{2013/05/02},{2013/05/03}"
finalDates="{$valid_data_range}"
printf "%s\n" "$finalDates"
printf "%s\n" $finalDates

产生:

  1. ksh

    {{2013/05/01},{2013/05/02},{2013/05/03}}
    {2013/05/01}
    {2013/05/02}
    {2013/05/03}
    
  2. bash (also zsh)

    {{2013/05/01},{2013/05/02},{2013/05/03}}
    {{2013/05/01},{2013/05/02},{2013/05/03}}
    
因此,在需要使用变量$finalDates时,请确保它在双引号内:
other_command "$finalDates"
if [ "$finalDates" = "$otherString" ]
then : whatever
else : something
fi

Etc - 使用您喜欢的布局来处理我不喜欢的任何内容。


4

您可以说:

finalDates=$'{'"$valid_data_range"$'}'

这本身是不起作用的;当使用变量时,必须防止其扩展。换句话说,问题不在于赋值,而在于“print”命令。 - Jonathan Leffler
谢谢大家的参与。如果我想使用已分配的变量,例如,如果我想将最终字符串传递给一个函数或另一个脚本(可能是Python或Perl脚本)来使用这个变量,我该怎么做? - axm2064
еңЁд»»дҪ•еј•з”ЁеҸҳйҮҸдё”дёҚеёҢжңӣеҸ‘з”ҹеӨ§жӢ¬еҸ·жү©еұ•зҡ„ең°ж–№пјҢдҪҝз”Ё"$finalDates"жҲ–е…¶еҸҳдҪ“пјҲдҫӢеҰӮ"${finalDates}"пјүгҖӮ - Jonathan Leffler

2
问题在于Shell正在执行花括号扩展操作。这允许您生成一系列类似的字符串:
$ echo {a,b,c}
a b c

这并不是非常令人印象深刻,但请考虑

$ echo a{b,c,d}e
abc ace ade

为了抑制大括号扩展,您可以使用set命令暂时关闭它。
$ set +B
$ echo a{b,c,d}e
a{b,c,d}e
$ set -B
$ echo a{b,c,d}e
abe ace ade

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