Take the 2-minute tour ×
Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems.. It's 100% free, no registration required.

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.

share|improve this question
add comment

6 Answers 6

up vote 4 down vote accepted

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
share|improve this answer
add comment

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
share|improve this answer
    
Curious: what do you mean be stick with bash? Isn't my approach already bash? –  Ketan Apr 29 at 20:56
    
@Ketan, I meant an approach that does not involve calling out to tools such as sed –  1_CR Apr 29 at 20:58
    
Got it, thanks. –  Ketan Apr 29 at 21:02
add comment

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)

share|improve this answer
    
You should be able to avoid the loop with printf "%s\n" "${arr[@]}" | paste -sd, –  1_CR Apr 29 at 21:10
    
thanks, improvement made –  Aaron Davies Apr 30 at 16:04
add comment

For the array a=(1 2 3 4 5)

If you can modify the array:

for (( i=$((${#a[@]}-1)); i-->0; )); do a[i]+=","; done
echo "${a[@]}"
1, 2, 3, 4, 5

$(( ${#a[@]} - 1 )) calculates the last-but-one array index and a[i]+="," appends a string.

If you want to do it in a function:

print_with_commas() {
        while [[ $# -gt 1 ]];do echo -n "$1, ";shift;done;echo "$1"
}
print_with_commas "${a[@]}"
1, 2, 3, 4, 5

Pop off each argument to the function, except the last, and echo with ", " appended with no newline. Then echo the last argument and newline.

share|improve this answer
add comment
$ w=(a b c)

$ IFS=, eval 'echo "${w[*]}"'
a,b,c

Side note, aren’t we reinventing the wheel here?

share|improve this answer
add comment

check the following script

$ cat run.sh
#!/bin/bash
echo example 1
for i in a b c; do echo "${i},"; done
echo example 2
for i in a b c; do echo "${i},"; done|sed '$s/,//'
echo example 3
for i in a b c; do echo "${i}"; done|sed '$!s/$/,/'
echo example 4
SEP=''; for i in a b c; do printf "${SEP}${i}"; SEP=',\n'; done; printf '\n'
echo example 5
STR=''; SEP=''; for i in a b c; do STR="${STR}${SEP}${i}"; SEP=,; done; echo $STR
echo example 6
echo 'a,b,c,'||sed 's/^\(.*\),\(^,\)*$/\1\2/'
echo example 7
echo 'a,b,c,'|sed 's/.\w*$//'

It gives the following output

$ . run.sh
example 1
a,
b,
c,
example 2
a,
b,
c
example 3
a,
b,
c
example 4
a,
b,
c
example 5
a,b,c
example 6
a,b,c
example 7
a,b,c

example 1: our for-loop actually produces lines. The echo $x transforms this to a single line.

example 2: You can tell sed to process only the last line

example 3: You can tell sed to process all but the last line

example 4: you can program your for loop that you do some special processing when it is ececuted the first time: dont prepent ',\n' to the line. But in many cases you don't know when it is exectued the last time

example 5: the same as example 4 but you do not produce lines but simply a string

example 6: tell sed to remove the last occurrence of a string in a line

example 7: tell sed to remove the last non whitespace character of a line

share|improve this answer
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.