Remove last comma from a bash for loop generated string

20,108

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?

Share:
20,108
Ketan Maheshwari
Author by

Ketan Maheshwari

Updated on September 18, 2022

Comments

  • Ketan Maheshwari
    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 into sed 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
    Ketan Maheshwari about 10 years
    Curious: what do you mean be stick with bash? Isn't my approach already bash?
  • Mathias Begert
    Mathias Begert about 10 years
    @Ketan, I meant an approach that does not involve calling out to tools such as sed
  • Mathias Begert
    Mathias Begert about 10 years
    You should be able to avoid the loop with printf "%s\n" "${arr[@]}" | paste -sd,
  • Robert Smith
    Robert Smith over 4 years
    Appreciate you putting this in here. This is my way of thinking as well and I've used your solution.