28

I'd like

$ echo a{b,c,d}

to output a comma-separated list like

ab,ac,ad

instead of the usual output

ab ac ad

What's the easiest way to do that on the command line?

0

6 Answers 6

18

Assuming that the elements do not contain spaces, you could translate spaces to commas:

echo a{b,c,d} | tr ' ' ,

which produces:

ab,ac,ad

You can also use ranges with characters:

echo a{b..d} | tr ' ' ,

This is especially useful if you want a larger range.

18

It seems bash does not use $IFS to join the generated words. Another technique would be to store the generated words in an array and then $IFS will be in play:

I'm going to use a subshell so I don't alter this shell's IFS: pick one of

( words=( a{b,c,d} ); IFS=,; echo "${words[*]}" )
( set -- a{b,c,d}; IFS=,; echo "$*" )

That emits the comma-separates string to stdout. If you want to capture it:

joined=$( set -- a{b,c,d}; IFS=,; echo "$*" )
1
  • It does not join the generated words at all. That's the whole point, it expands to separate words. Commented Aug 10, 2018 at 9:20
6

I am sure there are many ways to accomplish this. Here is one method:

echo a{b,c,d} | sed 's/ /,/g'
1
2

Here's a bash-only solution.

(IN=$(echo a{b,c,d}); echo ${IN// /,})
# ab,ac,ad

The part before the semicolon assigns ab ac ad to the variable IN and the second part uses search and replace to change all spaces to commas. The // means all matches, not just the first.

Do it all in a subshell (the enclosing parentheses) to not pollute your namespace.

2

Expand the elements like you showed and then loop over them, adding the comma to all but the first iteration:

for i in a{b,c,d}; do
  u="${u:+$u, }$i"
done
echo "$u"

Result:

ab, ac, ad

See bash parameter substitution.

1

It's worth noting that in many contexts, a trailing comma is acceptable in such a list. IF a trailing comma is acceptable, the easiest way to handle the substitution is printf:

some-command "$(printf %s, a{b,c,d} )"

(Where some-command is a command that runs on a comma separated list, and doesn't care about a trailing comma.)

Actually, even if you must not have a trailing comma you can use printf; you just need to specify the number of arguments you expect, which makes it clumsier for very long lists:

some-command "$(printf %s,%s,%s a{b,c,d} )"

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .