Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Bash: Why is echo adding extra space?

Tags:

syntax

bash

echo

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

like image 541
Dan Avatar asked Jan 05 '10 01:01

Dan


2 Answers

use the more portable printf

$ printf "D%s.jpg\n" {a,b,c}
Da.jpg
Db.jpg
Dc.jpg
like image 176
ghostdog74 Avatar answered Oct 13 '22 01:10

ghostdog74


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
like image 41
James Polley Avatar answered Oct 13 '22 01:10

James Polley