axm2064
axm2064

Reputation: 149

escape curly braces in unix shell script

I have a string:

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

I want to append a { at the beginning and a } at the end. The output should be:

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

However, in my shell script when I concatenate the curly braces to the beginning and end of the string, the output is as follows:

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

Why does this happen? How can I achieve my result? Am sure there is a simple solution to this but I am a unix newbie, thus would appreciate some help.

Test script:

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

Upvotes: 14

Views: 22448

Answers (3)

Jonathan Leffler
Jonathan Leffler

Reputation: 754520

The problem is that when you have a list in braces outside quotes, the shell performs Brace Expansion (bash manual, but ksh will be similar). Since the 'outside quotes' bit is important, it also tells you how to avoid the problem — enclose the string in quotes when printing:

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

(The print command is specific to ksh and is not present in bash. The change in the assignment line is more cosmetic than functional.)

Also, the brace expansion would not occur in bash; it only occurs when the braces are written directly. This bilingual script (ksh and bash):

valid_data_range="{2013/05/01},{2013/05/02},{2013/05/03}"
finalDates="{$valid_data_range}"
printf "%s\n" "$finalDates"
printf "%s\n" $finalDates

produces:

  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}}
    

Thus, when you need to use the variable $finalDates, ensure it is inside double quotes:

other_command "$finalDates"
if [ "$finalDates" = "$otherString" ]
then : whatever
else : something
fi

Etc — using your preferred layout for whatever you don't like about mine.

Upvotes: 5

chepner
chepner

Reputation: 531808

The problem is that the shell is performing brace expansion. This allows you to generate a series of similar strings:

$ echo {a,b,c}
a b c

That's not very impressive, but consider

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

In order to suppress brace expansion, you can use the set command to turn it off temporarily

$ set +B
$ echo a{b,c,d}e
a{b,c,d}e
$ set -B
$ echo a{b,c,d}e
abe ace ade

Upvotes: 2

devnull
devnull

Reputation: 123608

You can say:

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

Upvotes: 4

Related Questions