I get:
$ echo -e "D"{a,b,c}".jpg\n"
Da.jpg
Db.jpg
Dc.jpg
Note: The extra spaces before Db and Dc on the 2nd and 3rd line of the output.
Why are these there?
Thanks,
Dan
Edit: Since my actual objective had spaces in it (which I should have written originally):
echo -e "Name"{,.}" "{-,}"extra"{,so}" 5v5 "{one,two,No\ four}{,!,\!\!}"\n"
Most solutions here didn't work for me (for loop, xarg, tr). Printf didn't work because of multiple braces expansions that I want to cantesian product.
I combined 3 solutions (mletterle's \b, Dennis Williamson's extra space, and Jim Dennis's using far less quotes) to get:
echo -e "" \\bName{,.}\ {-,}extra{,so}\ 5v5\ {one,two,No\ four}{,\!,\!\!}\\n
Thanks all who answered! I learned a lot from your responses!
Dan
The easiest and cleanest solution is to add a backspace to the front of each line:
echo -e -n "\bD"{a,b,c}".jpg\n"
This produces the desired output.
use the more portable printf
$ printf "D%s.jpg\n" {a,b,c}
Da.jpg
Db.jpg
Dc.jpg
Because that's what brace expansion does. From man bash
, under the heading Brace expansion
:
Patterns to be brace expanded take the
form of an
optional preamble, followed by ... a series of comma-separated
strings ... followed by an optional
postscript. The preamble is prefixed
to each string contained within the
braces, and the postscript is then appended to each resulting
string, expanding left to right
For example, a{d,c,b}e expands into
‘ade ace abe’
So in your example, "D" is the preamble and ".jpg\n" is the postscript.
So, after brace expansion occurs, you're left with:
echo -e Da.jpg\n Db.jpg\n Dc.jpg\n
As hewgill points out, the shell then splits this into three tokens and passes them to echo; which outputs each token separated by a space. To get the output you want, you need to use one of the many suggestions here that don't re-inserted the unwanted space between tokens.
It's longer and probably not the neatest way to do this, but the following gives the output you're after:
for file in "D"{a,b,c}".jpg"
do
echo ${file}
done
echo
always adds spaces between arguments. Try your command without \n
and compare the results.
You can get the desired effect by using xargs to separate the arguments spit by the first echo into a line each:
$ echo "D"{a,b,c}".jpg" | xargs -n1 echo
Da.jpg
Db.jpg
Dc.jpg
You can get a more consistent look by prepending a null:
$ echo -en "" "D"{a..c}".jpg\n"
Da.jpg
Db.jpg
Dc.jpg
Now they all have an extra space. Also, using -n
eliminates the extra newline at the end. Also, you can use a range in your brace expansion.
Here is a solution using sed
(that builds upon https://stackoverflow.com/a/2003856/8180143):
$ echo -en "" "D"{a..c}".jpg\n" | sed 's/ //'
Da.jpg
Db.jpg
Dc.jpg
This solution has the advantage of working with inputs having spaces, e.g.,
$ echo -en "" "D "{a..c}".jpg\n" | sed 's/ //'
D a.jpg
D b.jpg
D c.jpg