web-dev-qa-db-fra.com

Compter le nombre de noms différents dans un fichier

Je veux compter le nombre de noms différents dans un fichier texte de cette présentation:

2008 girl Avah
2009 girl Avah
2008 girl Carleigh
2011 girl Kenley
2012 boy Joseph
2013 boy Joseph
2014 boy Isaac
2014 boy Brandon

Donc, fondamentalement, je veux ignorer le doublon et avoir comme réponse 6. J'ai essayé avec awk d'accéder uniquement à la troisième colonne, mais je n'arrive pas à faire imprimer le nombre de lignes.

6
Rebi Khalifa

Étant donné que votre fichier semble être pré-trié dans la colonne de nom, vous pouvez utiliser uniq avec le -f (--skip-fields) option pour afficher uniquement la première ligne de chaque nom et compter les lignes:

uniq -f2 FileName | wc -l

ou

uniq --skip-fields=2 FileName | wc -l

Si vos données sont pas pré-triées, vous pouvez combiner sort -u avec un -k spécification de champ pour obtenir la même chose (bien que cela ne soit pas clairement documenté dans la page de manuel GNU sort):

sort -uk3 FileName | wc -l

C'est exagéré pour cette tâche, mais vous pouvez également utiliser GNU Datamash:

datamash -W countunique 3 < FileName
6
steeldriver

avec awk:

<fileName awk '!nameSeen[$3]++{ count++ } END{ print count }'

si un nouveau nom est trouvé !nameSeen[$3]++ incrémenter le compteur count++ et à la valeur du compteur d'impression END.

6
αғsнιη

Un moyen très court et facile, en utilisant Miller ( https://github.com/johnkerl/miller )

mlr --nidx uniq -g 3 -n input.txt
2
aborruso

Un moyen rapide assez simple qui s'explique:

cat FileName | sed 's/[0-9]*//g' | sed 's/\<boy\>//g' | sed 's/\<girl\>//g' | sort -u | wc -l

Ou pour satisfaire @ αғsнιη's préoccupation concernant oC :

<FileName sed 's/[0-9]*//g' | sed 's/\<boy\>//g' | sed 's/\<girl\>//g' | sort -u | wc -l

Ou une autre commande conforme oC :

sed 's/[0-9]*//g' <FileName | sed 's/\<boy\>//g' | sed 's/\<girl\>//g' | sort -u | wc -l

Un avis à @ Rebi Khalifa :

@ αғsнιη à juste titre écrit dans les commentaires au dessous de:

ou <fileName cut -d' ' -f3 |sort -u |wc -l; cat filename | ... Est oC

@ steeldriver à juste titre écrit dans les commentaires au dessous de:

Je suggère d'utiliser cut plutôt que toutes ces commandes sed - vous devez au moins les combiner en un seul ex d'invocation. sed -E -e 's/^[0-9]+//' -e 's/\b(boy|girl)\b//'

Ils ont tous deux utilisé l'approche de sélection de champ qui est la même approche que vous essayiez à mettre en œuvre pour résoudre votre problème basé sur ce que vous avez écrit dans votre question:

J'ai essayé avec awk d'accéder uniquement à la troisième colonne mais je n'arrive pas à imprimer le nombre de lignes.


Il n'est pas nécessaire d'être sophistiqué pour faire avancer les choses dans Ubuntu! Les choses peuvent se faire de nombreuses manières inimaginables.

Une façon de faire l'éloge du principe KISS est de diriger les commandes simples | L'une vers l'autre jusqu'à la fin de la mission:

  • Lisez le contenu du fichier avec cat FileName ->
  • Tuyau | ->
  • Supprimer les groupes de numéros avec sed 's/[0-9]*//g' ->
  • Tuyau | ->
  • Supprimez le mot garçon avec sed 's/\<boy\>//g' ->
  • Tuyau | ->
  • Supprimer la fille Word avec sed 's/\<girl\>//g' ->
  • Seuls noms sont laissés maintenant ... ->
  • Pipe it | ->
  • Triez les noms et supprimez les doublons avec sort -u ->
  • Il ne reste plus que noms uniques ->
  • Tuyau | ->
  • Comptez les lignes avec wc -l ->
  • Terminé
2
Raffa