1
votes

Compter le nombre de valeurs uniques en fonction de deux colonnes dans bash

J'ai un fichier séparé par des tabulations qui ressemble à ceci:

awk -F " "'{print $1}' file.tsv | uniq -c
cut -d' ' -f1,2 file.tsv | sort | uniq -ci

En gros, j'ai besoin de décomptes de valeurs uniques appartenant à la première colonne, le tout dans un seul commando avec des pipelines. Comme vous pouvez le voir, il peut y avoir des doublons comme "A 1234". J'avais quelques idées avec awk ou cut, mais aucune des deux ne semble fonctionner. Ils impriment simplement toutes les paires uniques, alors que j'ai besoin de compter des valeurs uniques de la deuxième colonne en tenant compte de la valeur de la première.

A 1234
A 123245
A 4546
A 1234
B 24234
B 4545
C 1234
C 1234

Output: 
A 3
B 2
C 1

I J'apprécierais vraiment votre aide! Merci en avance.


2 commentaires

sort + uniq puis ceci


Pourquoi utilisez-vous cut -d '' (c'est-à-dire dire à cut d'utiliser un blanc au lieu d'une tabulation comme séparateur) lorsque votre fichier est séparé par des tabulations?


5 Réponses :


4
votes

Avec une solution complète de awk , vous pouvez essayer la suite.

awk '                  ##Starting awk program from here.
BEGIN{
  FS=OFS="\t"
}
!found[$0]++{       ##Checking condition if 1st and 2nd column is NOT present in found array then do following.
  val[$1]++            ##Creating val with 1st column inex and keep increasing its value here.
}
END{                   ##Starting END block of this progra from here.
  for(i in val){       ##Traversing through array val here.
    print i,val[i]     ##Printing i and value of val with index i here.
  }
}
'  Input_file          ##Mentioning Input_file name here.

Explication: Ajout d'une explication détaillée ci-dessus.

awk 'BEGIN{FS=OFS="\t"} !found[$0]++{val[$1]++} END{for(i in val){print i,val[i]}}' Input_file


6 commentaires

Merci, mais j'obtiens toujours quelque chose comme: A 1234 2 // A 123245 1 // A 4546 1 etc.


@ ta4le, cela a bien fonctionné pour moi avec des exemples donnés, pourriez-vous s'il vous plaît me faire savoir si votre fichier_entrée réel est le même que celui des exemples illustrés?


@ ta4le, votre fichier d'entrée est-il séparé par une virgule? Veuillez confirmer la même chose une fois.


non, c'est plus compliqué mais la sémantique est la même: deux colonnes, des clés et des valeurs multiples pour elles. Tabulation séparée


@ ta4le, ok si son TAB s'est séparé, j'ai fait des changements dans mon code où j'ai fait un séparateur de champ comme TAB, veuillez le vérifier une fois et me le faire savoir alors.


Je suggère d'utiliser found [$ 0] au lieu de found [$ 1, $ 2]



1
votes

Vous pouvez essayer ceci:

cat file.tsv | sort | uniq | awk '{print $1}' | uniq -c | awk '{print $2 " " $1}'

Cela fonctionne pour votre exemple. (Mais je ne suis pas sûr que cela fonctionne pour d'autres cas. Faites-moi savoir si cela ne fonctionne pas!)


0 commentaires

2
votes

Utilisation de GNU awk:

 $ gawk -F\\t '{               # using GNU awk and tab as delimiter
    a[$1][$2]                  # hash to 2D array
 }
 END {                         
     for(i in a)               # for all values in first field
         print i,length(a[i])  # output value and the size of related array
 }' file

Sortie:

A 3
B 2
C 1

Expliqué:

$ gawk -F\\t '{a[$1][$2]}END{for(i in a)print i,length(a[i])}' file


0 commentaires

1
votes
$ sort -u file | cut -f1 | uniq -c
   3 A
   2 B
   1 C

0 commentaires

1
votes

Une autre façon, en utilisant l'utilitaire GNU datamash :

$ datamash -g1 countunique 2 < input.txt
A   3
B   2
C   1


0 commentaires