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.

How can I use awk to run through a file written as:

Sarah,Masha,Helen
Connor,Jessica,Jennifer,Candace
Betty,Sarah,Helen
John,Harold,Frank,Daisy

and put out all pairs that appeared in a line together without any repeats (Sarah Helen would appear only once here)? meaning,

Sarah Masha
Sarah Helen
Masha Helen
Connor Jessica
etc.

I've been trying to make some kind of for loop but it isn't working for me...

share|improve this question
    
Does it need to be awk? –  terdon Feb 28 at 2:34
    
yeah :( @terdon –  Jenny Feb 28 at 2:34
    
Can this be gawk or do you need to use non-GNU awk? If gawk, which version? The newer ones have some cool sorting functions that can be used for this. Should Helen Marsha be considered a dupe of Marsha Helen? –  terdon Feb 28 at 2:46
add comment

3 Answers 3

Here is an awk solution:

% awk -F, '
{
    for(i = 1; i < NF; i++) {
        for(j = i+1; j <= NF; j++) {
            if(length(a[$i,$j]) == 0) {
                if(length(a[$j,$i]) > 0) {
                    next;
                }
                a[$i,$j]=$i" "$j;
                print a[$i,$j];
            }
        }
    }
}' file
Sarah Masha
Sarah Helen
Masha Helen
Connor Jessica
Connor Jennifer
Connor Candace
Jessica Jennifer
Jessica Candace
Jennifer Candace
Betty Sarah
Betty Helen
John Harold
John Frank
John Daisy
Harold Frank
Harold Daisy
Frank Daisy
share|improve this answer
    
Congrats on getting to 2K! –  slm Feb 28 at 2:38
    
Nice (and congrats indeed), but the OP wants to avoid dupes as well. You have Sarah Helen twice. –  terdon Feb 28 at 2:38
    
Run the output to awk ... | sort -u –  slm Feb 28 at 2:42
1  
@slm not if the names can appear in different order, my understanding is that Masha Helen should count as a dupe of Helen Masha. –  terdon Feb 28 at 2:43
    
@terdon - yeah just a thought, not sure if order mattered. –  slm Feb 28 at 2:44
show 7 more comments

I am assuming that the names can appear in any order and that Helen Sarah should therefore be considered as a duplicate of Sarah Helen. If so, this should do what you want. It is very similar to Gnouc's answer but can deal with dupes that appear in different order.

I used a slightly different input file than yours so I could test for more cases:

Sarah,Masha,Helen
Betty,Sarah,Helen
John,Harold,Frank,Daisy
Masha,Sarah,Helen,Gerorge
Helen,Sarah,Masha

Here's the gawk as a one liner and it's output:

$ awk -F, '{for(i=1;i<NF;i++){for(j=i+1;j<=NF;j++){if($i > $j){k[$i][$j]}else{k[$j][$i]}}}}END{for(n in k){for (l in k[n]){print n,l}}}' names.txt  
John Daisy
John Frank
John Harold
Sarah Masha
Sarah Betty
Sarah Helen
Frank Daisy
Masha Helen
Harold Daisy
Harold Frank
Helen Betty

And here's the same thing broken down:

{
    ## For all fields from first to penultimate
    for(i=1;i<NF;i++){
      ## For all fields from second to last
      for(j=i+1;j<=NF;j++){
        ## This is to avoid duplicates, $i and $j are names
        ## by comparing (sorting) them, I make sure that they
        ## will be stored in the array consistently so I will
        ## count 'Dick Harry' as a duplicate of 'Harry Dick'
        if($i > $j){
          k[$i][$j]
        }
        else{
          k[$j][$i]
        }
    }
  }
}
END{
    ## Go through the array k tath holds the name pairs
    for(n1 in k){
      ## It is a  2 dimensional array so n1 is the first name
      ## and n2 will be the second
      for (n2 in k[n1]){
          print n1,n2
      }
    }
}
share|improve this answer
    
my answer produce the same output with yours. At first, I think a solution like yours, but it doesn't serve the order of input. –  Gnouc Feb 28 at 3:31
    
@Gnouc yes, I know they produce the same output (well, different sort order but same information), that's because they're both correct :). I don't see how the sort order (in terms of which line is printed first) could be relevant here, the OP needs to remove duplicate entries so the sort order will change by definition. –  terdon Feb 28 at 3:34
    
Interesting new feature. The multidimensional array, or rather multiple arrays for every first index, needs gawk 4.x –  Scrutinizer Feb 28 at 8:32
add comment

Another awk

awk -F, '
  {
    for(i=1; i<=NF; i++)
      for(j=i+1; j<=NF; j++)
        if(!(A[$i,$j]++*A[$j,$i]++))
          print $i,$j
  }
' file
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.