escape curly braces in unix shell script
Asked Answered
B

3

14

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
Ballonet answered 10/10, 2013 at 9:18 Comment(0)
B
5

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.

Befoul answered 10/10, 2013 at 14:13 Comment(0)
I
4

You can say:

finalDates=$'{'"$valid_data_range"$'}'
Ingenuous answered 10/10, 2013 at 9:24 Comment(3)
This on its own does not work; you have to prevent the expansion when the variable is used. The problem is not the assignment, in other words; it is the print command.Befoul
Thanks for the input everyone. So if I want to use the assigned variable, for example, if I want to pass the final string to a function or to another script (maybe python, or perl script) that will use this variable, how can I do that?Ballonet
Use "$finalDates" or a variation on that (such as "${finalDates}") anywhere you reference the variable and don't want the brace expansion to occur.Befoul
D
2

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
Delay answered 10/10, 2013 at 13:51 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.