Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

echo combinations with special character as elements

I've a small script which takes advantage of the echo ability to generate combinations of elements. That's the piece of code,

set={1,2,3,4}
group=3
for ((i=0; i<$group; i++));
do
  repetition=$set$repetition
done

bash -c "echo "$repetition""

That works fine, the problem comes when I want the set to consist of some special characters, like commas, parenthesys, etc. I've tried with scapes but it doesn't seem to work, something like

set={(,),\,,=}

Any clue about how to achieve it?

like image 554
Toni Avatar asked Dec 11 '25 09:12

Toni


2 Answers

You need to quote and escape:

set={1,2,3,"\'4\'"}

Note that it was working with {1,2,3,4} because it is digits. For strings you also need to quote: {1,2,3,'a'}

$ echo {1,2,3,'a'}{1,2,3,'a'}
11 12 13 1a 21 22 23 2a 31 32 33 3a a1 a2 a3 aa

And then the escaping is to handle the execution of bash -c together with the values.


From your comments, your final script is:

set={"\(","\)","\,"}
group=3
for ((i=0; i<$group; i++));
do
  repetition=$set$repetition
done

bash -c "echo "$repetition""

When I execute it I get this, nice!

$ ./a
((( (() ((, ()( ()) (), (,( (,) (,, )(( )() )(, ))( ))) )), ),( ),) ),, ,(( ,() ,(, ,)( ,)) ,), ,,( ,,) ,,,
like image 82
fedorqui 'SO stop harming' Avatar answered Dec 12 '25 23:12

fedorqui 'SO stop harming'


While @fedorqui's answer is the way to go, here's a bit more information for completeness. You know that special characters need to be escaped, but \ is, itself a special character so that needs to be escaped as well since you are passing it to another bash instance.

So, when you have set={(,)} in your script, your script will throw a syntax error because of the parentheses. Once you escape them as set={\(,\)} your script is OK with them but has already expanded them by the time you pass them to your bash -c which instead will see set={( )} and choke on that, giving the same syntax error:

$ set={\(,\)}; echo Parent: "$set";  bash -c "echo Child1: "$set""
Parent: {(,)}
bash: -c: line 0: syntax error near unexpected token `('
bash: -c: line 0: `echo Child1: {(,)}'

The obvious solution would be to escape the backslashes themselves, so they will be passed correctly. However, escaping causes a character to loose its special powers, so escaping the \ will stop it from escaping the parentheses:

$ set={\\(,\\)};
bash: syntax error near unexpected token `('

So, back to square one. What you have to do is escape the escape that is escaping the escape1:

$ set={\\\(,\\\)}
$ echo "Parent3: $set"
Parent3: {\(,\)}
$ bash -c "echo Child3 "$set""
Child3 ( )

Here, the child instance is finally being passed what it needs to see: {\(,\)}. So, while it is not strictly necessary to use quotes in such cases, they really make your life much, much easier:


1 Try saying that 5 times quickly.

like image 34
terdon Avatar answered Dec 13 '25 01:12

terdon



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!