Quelle est la différence entre ce qui suit et les commandes?
sort -u FILE
sort FILE | uniq
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).
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.
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.
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
Rien, ils vont produire le même résultat
J'ai travaillé sur des serveurs où sort ne prend pas en charge l'option '-u'. là nous devons utiliser
sort xyz | uniq