Ne confondez pas cette question avec un doublon de "quelle est la différence n/b sort -u et sort | uniq"
Il s'agit essentiellement d'un programme de comptage de mots
La confusion suscitée par la commande suivante est la raison de poser cette question:
root@sanctum:~/datascience# cat data
this is a file that is supposed to be a file
cela donne une sortie incorrecte:
root@sanctum:~/datascience# cat data | sed 's/ /\n/g' | uniq -c
1 this
1 is
1 a
1 file
1 that
1 is
1 supposed
1 to
1 be
1 a
1 file
Le fait de canaliser la sortie pour trier puis vers uniq donne la réponse parfaite
root@sanctum:~/datascience# cat data | sed 's/ /\n/g' | sort |uniq -c
2 a
1 be
2 file
2 is
1 supposed
1 that
1 this
1 to
sortie lorsque canalisé juste pour trier:
root@sanctum:~/datascience# cat data | sed 's/ /\n/g' | sort
a
a
be
file
file
is
is
supposed
that
this
to
comment le numéro de ligne d'apparence d'une ligne a-t-il un effet sur le nombre d'occurrences dans le fichier? je ne sais pas comment le formuler mais vous obtenez le point
Fondamentalement, pourquoi ne peux pas cat data | sed 's/ /\n/g' | uniq -c
donne le résultat souhaité?
Ce n'est pas un comportement aléatoire. De man uniq
:
Remarque: 'uniq' ne détecte pas les lignes répétées à moins qu'elles ne soient adjacentes. Vous voudrez peut-être d'abord trier l'entrée ou utiliser 'sort -u' sans 'uniq'. De plus, les comparaisons respectent les règles spécifiées par 'LC_COLLATE'.
Essentiellement, uniq
par défaut ne fonctionne que sur l'entrée triée. Il en est ainsi par conception, en d'autres termes.
Cependant, votre question principale est:
comment le numéro d'apparence d'une ligne a-t-il un effet sur le nombre d'occurrences dans le fichier
Pour répondre à cette question, il faudrait vraiment regarder le code source:
while (!feof (stdin))
{
char *thisfield;
size_t thislen;
if (readlinebuffer_delim (thisline, stdin, delimiter) == 0)
break;
thisfield = find_field (thisline);
thislen = thisline->length - 1 - (thisfield - thisline->buffer);
if (prevline->length == 0
|| different (thisfield, prevfield, thislen, prevlen))
{
fwrite (thisline->buffer, sizeof (char),
thisline->length, stdout);
SWAP_LINES (prevline, thisline);
prevfield = thisfield;
prevlen = thislen;
}
}
La clé ici est que le fichier est lu ligne par ligne et la comparaison ne peut être effectuée qu'avec la ligne actuelle et la ligne précédente dans la fonction different()
qui renvoie True si les lignes ne sont pas les mêmes , Faux s'ils sont identiques. La raison en est que si vous comparez avec toutes les lignes , vous aurez probablement besoin d'une grande quantité de mémoire s'il y a un grand nombre de lignes. Ce n'est pas pratique et ralentirait considérablement uniq