Lista todos os pares de palavras que aparecem em uma linha juntos em um arquivo

2

Como posso usar o awk para percorrer um arquivo escrito como:

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

e colocar todos os pares que apareceram em uma linha juntos sem qualquer repetição (Sarah Helen apareceria apenas uma vez aqui)? significado,

Sarah Masha
Sarah Helen
Masha Helen
Connor Jessica
etc.

Eu tenho tentado fazer algum loop, mas não está funcionando para mim ...

    
por Jenny 28.02.2014 / 03:18

3 respostas

4

Aqui está uma solução awk :

% 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
    
por 28.02.2014 / 03:36
2

Estou assumindo que os nomes podem aparecer em qualquer ordem e que Helen Sarah deve, portanto, ser considerado como uma duplicata de Sarah Helen . Se assim for, isso deve fazer o que você quer. É muito semelhante à resposta de Gnouc, mas pode lidar com enganos que aparecem em ordem diferente.

Eu usei um arquivo de entrada ligeiramente diferente do seu para poder testar mais casos:

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

Aqui está o gawk como um forro e sua saída:

$ 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

E aqui está a mesma coisa:

{
    ## 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
      }
    }
}
    
por 28.02.2014 / 04:05
0

Outro 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
    
por 28.02.2014 / 08:55

Tags