web-dev-qa-db-fra.com

Trier et uniq dans un shell Linux

Quelle est la différence entre ce qui suit et les commandes?

sort -u FILE

sort FILE | uniq
47
yassin

En utilisant sort -u fait moins d’E/S que sort | uniq, mais le résultat final est le même. En particulier, si le fichier est assez gros pour que sort doive créer des fichiers intermédiaires, il y a de bonnes chances que sort -u utilisera un nombre légèrement inférieur ou un peu plus petit de fichiers intermédiaires, car cela pourrait éliminer les doublons car il trie chaque ensemble. Si les données sont hautement redondantes, cela pourrait être bénéfique; s'il y a peu de doublons en fait, cela ne fera pas beaucoup de différence (un effet de performance de second ordre, bien sûr, comparé à l'effet de premier ordre du tuyau).

Notez que la tuyauterie est parfois appropriée. Par exemple:

sort FILE | uniq -c | sort -n

Cela trie le fichier dans l'ordre du nombre d'occurrences de chaque ligne du fichier, les lignes les plus répétées apparaissant en dernier. (Cela ne me surprendrait pas de constater que cette combinaison, qui est idiomatique pour Unix ou POSIX, peut être décomposée en une commande 'sort' complexe avec GNU sort.)

Il est parfois important de ne pas utiliser le tuyau. Par exemple:

sort -u -o FILE FILE

Ceci trie le fichier 'in situ'; c'est-à-dire que le fichier de sortie est spécifié par -o FILE, et cette opération est garantie en toute sécurité (le fichier est lu avant d'être écrasé pour la sortie).

79
Jonathan Leffler

Il y a une légère différence: le code de retour.

La chose est que, à moins que shopt -o pipefail est défini le code de retour de la commande piped sera le code de retour de la dernière. Et uniq renvoie toujours zéro (succès). Essayez d'examiner le code de sortie, et vous verrez quelque chose comme ceci (pipefail n'est pas défini ici):

pavel@lonely ~ $ sort -u file_that_doesnt_exist ; echo $?
sort: open failed: file_that_doesnt_exist: No such file or directory
2
pavel@lonely ~ $ sort file_that_doesnt_exist | uniq ; echo $?
sort: open failed: file_that_doesnt_exist: No such file or directory
0

Autre que cela, les commandes sont équivalentes.

10
P Shved

Il faut se méfier! S'il est vrai que "sort -u" et "sort | uniq" sont équivalents, toute option supplémentaire de trier peut rompre l'équivalence. Voici un exemple tiré du manuel coreutils:

Par exemple, 'sort -n -u' inspecte uniquement la valeur de la chaîne numérique initiale lors de la vérification de l'unicité, alors que 'sort -n | uniq' inspecte la ligne entière.

De même, si vous triez sur des champs clés, le test d'unicité utilisé par tri ne concernera plus nécessairement la ligne entière. Après avoir été piqué par ce bogue dans le passé, j'ai tendance à utiliser "sort | uniq" lors de l'écriture de scripts Bash. Je préfère avoir une surcharge d'E/S plus élevée que de courir le risque que quelqu'un d'autre dans la boutique ne connaisse pas cet écueil particulier lorsqu'il modifie mon code pour ajouter des paramètres de tri supplémentaires.

8
willdye

sort -u sera légèrement plus rapide, car il n’a pas besoin de diriger la sortie entre deux commandes

voir aussi ma question sur le sujet: appeler uniq et trier les différents ordres dans Shell

6
knittl

Rien, ils vont produire le même résultat

2
Jauzsika

J'ai travaillé sur des serveurs où sort ne prend pas en charge l'option '-u'. là nous devons utiliser

sort xyz | uniq
1
Hemant