Take the 2-minute tour ×
Server Fault is a question and answer site for professional system and network administrators. It's 100% free, no registration required.

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)

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

4 Answers

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

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

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

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.

share|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
add comment

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

Sort is your friend: Sort Wiki.

As is Awk: Awk Howto.

share|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

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.