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?
Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems. It only takes a minute to sign up.
Sign up to join this communityAssuming 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.
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 "$*" )
I am sure there are many ways to accomplish this. Here is one method:
echo a{b,c,d} | sed 's/ /,/g'
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.
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
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} )"