Je dois compter le nombre de valeurs uniques en fonction de deux colonnes dans une feuille de calcul.
Supposons que le fichier ressemble à ceci, classé par nom, prénom, société:
joe allen ibm
joe smith ibm
joe allen google
joe smith google
rachel allen google
Et je dois compter le nombre de prénoms uniques pour chaque entreprise en ignorant le nom de famille:
joe ibm 2
joe google 2
rachel google 1
J'ai ce code:
sort file.tsv | uniq -ci | awk '{print $2,$1}'
Si je supprime simplement la colonne de nom de famille, ce code fonctionnera. Mais si je ne veux pas supprimer cette colonne, awk doit simplement l’ignorer et enregistrer le résultat dans un nouveau fichier?
Les données sont séparées par des onglets \t
Une solution GNU awk utilisant tableaux à deux dimensions :
gawk -F $'\t' '{a[$1][$3]++} END {for (i in a) for (j in a[i]) print i, j, a[i][j]}' foo.txt
a[$1][$3]++
pour chaque combinaison de prénom et nom, incrémenter le nombreUne autre façon de travailler avec les autres awk
s utilisant l'ancienne forme de tableaux multidimensionnels:
awk -F $'\t' '{a[$1, $3]++} END{for (i in a) {split (i, sep, SUBSEP); print sep[1], sep[2], a[i]}}' foo.txt
SUBSEP
, nous devons le scinder sur SUBSEP
pour récupérer les index d'origine.Voici une solution Pythonic utilisant le module Counter
de collections
qui comptera le nombre d'occurrences de chaque élément dans un élément itératif:
#!/usr/bin/env python2
import collections
with open('file.txt') as f:
names = []
for line in f:
names.append(line.strip().split()[0] + ' ' + line.strip().split()[2])
result_dict = collections.Counter(names)
for person in result_dict:
print person + ' ' + str(result_dict[person])
Vous pouvez utiliser cut
pour sélectionner les colonnes que vous souhaitez utiliser en premier. Donc, étant donné que vos colonnes sont séparées par un espace, et sont FNAME SNAME COMPANY où nous ne sommes intéressés que par les colonnes 1 et 3, nous pouvons utiliser:
cut -d' ' -f1,3 file.tsv | sort | uniq -ci
Ceci indique à cut
de se séparer en utilisant un seul espace '' comme séparateur et de passer les colonnes 1 et 3 en tri.
Il produira une sortie similaire à:
cut -d' ' -f1,3 file.tsv | sort | uniq -ci
2 joe google
2 joe ibm
1 rachel google
Le Perl oneliner suivant extraira les données pour vous:
Perl -e '/(.*)\t.*\t(.*)/ and $a{"$1 $2"}++ for (<>); print "$_ $a{$_}\n" foreach (keys%a);' file.tsv
Sortie:
joe ibm 2
joe google 2
rachel google 1