When you use brace expansion in bash, something like
echo {a,b,c}
becomes
echo a b c
Is there a way to expand it to 3 separate commands, one for each expansion, instead?
So that:
echo {a,b,c}
would become
echo a
echo b
echo c
Is this just a "because I wanna know" question, or is there a real use case for it? We could go through some gymnastics to get it done:
$ eval echo\ {a,b,c}\;
a
b
c
But I'd hunt down anyone that was putting in these kinds of obfuscatory commands into our system scripts.
Why not go for clarity instead:
$ for X in {a,b,c}; do echo $X; done
You could even go whole-hog and put in a couple of newlines and indent it a bit so that you'd always be able to understand what you were trying to do.
file-{r,b,g}{m,n,o}{x,y.z}.foo
then it's better to use the short form than enumerating all 27 value.
Jul 1, 2011 at 4:15
for
works for this, but it's still more typing :P
Jul 2, 2011 at 3:51
eval git branch -d \{ branch-a, branch-b }\;
Based on Mark Mann's selected answer, I was able to further derive this example, which works great:
$ eval echo\ category_{17,32,33}.properties\{,.bak\}\;
category_17.properties category_17.properties.bak
category_32.properties category_32.properties.bak
category_33.properties category_33.properties.bak
What that is showing, is when you are using multiple occurrences of brace expansion within a line, Mark's original example would have printed every variation individually. Instead, I wanted to use his answer to move/rename multiple files. To ensure that the output matched the format that mv
normally expects (mv oldfilename newfilename
), I escaped the second occurrence of brace expansion, so that it wouldn't be evaluated until after the initial eval
command had executed.
As the above output appeared as expected, I was then able to run the following command:
$ eval mv\ category_{17,32,33}.properties\{,.bak\}\;
$ ls
category_17.properties.bak category_32.properties.bak category_33.properties.bak
Many thanks to Mark for his original answer. Please up-vote his answer if you like what his answer allowed me to do :-)
$ echo {a,b,c} | xargs -n1
a
b
c
echo
, then we would need to supply it to xargs
explicitly (e.g. echo {a,b,c} | xargs -n1 cowsay
). (2) xargs
interprets quotes and backslashes. The behavior doesn't matter in this simple case, but in general it does. // +1 anyway.
Sep 29, 2020 at 16:32
printf '%s\n' echo{\ a,\ b,\ c}