Is it possible to transform this:

1 Alice
1 Bob
1 Cary
2 Dan
3 Eve
3 Fred 

into this:

1 Alice,Bob,Cary
2 Dan
3 Eve,Fred

using shell? (without Perl, Ruby, Python etc)

link|improve this question

29% accept rate
synapse, is this a school homework problem? It smells suspiciously like one, especially with the arbitrary limitation on how to solve the problem. – Phil Hollenback Mar 30 '11 at 7:47
feedback

4 Answers

Yes, there's a few ways of doing this.

Sort is your friend: Sort Wiki.

As is Awk: Awk Howto.

link|improve this answer
Jonathan, if he can't use perl/python, I'd rather assumed that all external utilities were banned. I suspect it can be done in pure bash, but it looks so much like a homework exercise I decided not to bother. Synapse, if this is a real problem, can you tell us a bit more about it, and which external tools are available to us? – MadHatter Mar 30 '11 at 6:39
@MadHatter We both read that question differently :-) – Jonathan Ross Mar 30 '11 at 6:41
<LARGE GRIN> sorry, absolutely; I am in no way critical of your answer, and sort, awk (and sed) were the first tools my mind reached for as well, I think your recommendation is a good one. I could do with a bit more information about the actual problem, is all! – MadHatter Mar 30 '11 at 6:43
@MadHatter Hehe :-) – Jonathan Ross Mar 30 '11 at 6:54
@MadHatter The real thing is the output of md5sum | sort | uniq which was fed to Ruby for grouping and db processing. I was wondering what is possible without "real" programming languages. – synapse Mar 30 '11 at 20:15
show 1 more comment
feedback

Using associative arrays in bash version 4:

declare -A ary
while read line; do
  set -- $line
  ary[$1]+="$2,"
done < input_file
for key in ${!ary[@]}; do
  printf "%s %s\n" $key ${ary[$key]%,}  # the "%," strips the trailing comma
done
link|improve this answer
feedback

Crap I couldn't resist the challenge. Here's my solution in shell (bash to be exact) as a oneliner:

k=0; while read i j; do if [ $k -eq $i ]; then echo -n ",$j"; \
else [ $k -gt 0 ] && echo; echo -n "$i $j"; k=$i; fi; done \
</tmp/infile; echo

which produces the desired output, properly formatted:

1 Alice,Bob,Cary
2 Dan
3 Eve,Fred

Assumptions:

  1. 0 is not a valid entry in the first column of the data.
  2. the first column is already numerically sorted.

If #2 is not valid, you need to run the input through sort(1) first with a numeric sort to put it in the proper order.

If I find out I just answered your homework I will be extremely annoyed. My only consolation is that if your teacher sees what I wrote they will think you are nuts.

link|improve this answer
No, that's not my homework. That's almost the last part of pipe to delete links to identical files in database wget/find/md5sum/sort/uniq/ruby. After I've written Ruby script to group and modify the db I was wondering if it's possible to do grouping using shell. – synapse Mar 30 '11 at 10:13
Just joking around, no offense meant.:) – Phil Hollenback Mar 30 '11 at 14:17
feedback

This one over at stackoverflow is very similar and has some good answers: http://stackoverflow.com/questions/380817/best-way-to-simulate-group-by-from-bash

link|improve this answer
That counts single entries, so I don't think it's applicable. – l0b0 Mar 30 '11 at 11:46
feedback

Your Answer

 
or
required, but never shown

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