Remove last comma from a bash for loop generated string
Solution 1
The issue was that, by default, echo
adds a new line each time it is called and sed
was operating on those new lines. You couldn't see that because, when bash processes $(...)
, those new lines are converted to spaces. So, to fix the problem while making the smallest change to your approach:
$ x=$(for i in a b c; do echo -n "${i}",; done| sed 's/,$//') ; echo $x
a,b,c
The option -n
tells echo
not to add new lines.
If you want spaces between the items, they are easily added:
$ x=$(for i in a b c; do echo -n "${i}, " ; done| sed 's/, $//') ;echo $x
a, b, c
Solution 2
One option is to stick with bash
arr=(a b c)
x=$(IFS=,;printf "%s" "${arr[*]}")
echo "$x"
a,b,c
Alternately
arr=(a b c)
printf -v x "%s," "${arr[@]}"
x=${x%,}
echo "$x"
a,b,c
With the second option, you can set the separator to ,
(comma followed by space) instead of ,
alone
printf -v x "%s, " "${arr[@]}"
x=${x%, }
echo "$x"
a, b, c
Solution 3
another useful technique for this is paste -s
:
$ arr=(a b c)
$ printf "%s\n" "${arr[@]}" | paste -sd,
a,b,c
(note that the paste -sd,
here is a very general "turn this set of newline-separated items into a comma-separated list" operation)
Solution 4
Why do you absolutely need to remove the last comma?
You're messing things up and then trying to clean up the mess afterward, instead of thinking correctly about the problem in the first place.
There is a solution when you look at the comma as not being located after each item but in front of each item.
for i in a b c; do
u="${u:+$u, }$i"
done
echo $u
See bash parameter substitution.
Result:
a, b, c
Solution 5
$ w=(a b c)
$ IFS=, eval 'echo "${w[*]}"'
a,b,c
Side note, aren’t we reinventing the wheel here?
Ketan Maheshwari
Updated on September 18, 2022Comments
-
Ketan Maheshwari almost 2 years
I am dealing with a situation where I need to create a comma separated list from an array into a heredoc and remove the last comma. I am using bash
for
piped intosed
which is erasing all commas instead of the last one. A simplified example is as follows:x=$(for i in a b c; do echo "${i}",; done| sed 's/,$//') echo $x a b c
Desired output:
a, b, c
Any suggestions appreciated.
-
Ketan Maheshwari about 10 yearsCurious: what do you mean be stick with bash? Isn't my approach already bash?
-
Mathias Begert about 10 years@Ketan, I meant an approach that does not involve calling out to tools such as
sed
-
Mathias Begert about 10 yearsYou should be able to avoid the loop with
printf "%s\n" "${arr[@]}" | paste -sd,
-
Robert Smith over 4 yearsAppreciate you putting this in here. This is my way of thinking as well and I've used your solution.