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
4

3 回答 3

4

问题是,当您在引号外的大括号中有一个列表时,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。分配行中的更改更美观而不是功能。)

此外,大括号扩展不会发生在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(也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

等等——使用你喜欢的布局来处理你不喜欢我的任何东西。

于 2013-10-10T14:13:42.463 回答
3

你可以说:

finalDates=$'{'"$valid_data_range"$'}'
于 2013-10-10T09:24:29.767 回答
2

问题是外壳正在执行大括号扩展。这允许您生成一系列类似的字符串:

$ 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
于 2013-10-10T13:51:10.383 回答