2009-08-31 16:20:22 +0000 2009-08-31 16:20:22 +0000
48
48

Comment faire un tri UNIX par une seule colonne ?

Je sais que l'option -k pour l'Unix sort nous permet de trier par une colonne spécifique et toutes les suivantes. Par exemple, étant donné le fichier d'entrée :

2 3
2 2
1 2
2 1
1 1

En utilisant sort -n -k 1, j'obtiens une sortie triée par la 1ère colonne et ensuite par la 2ème :

1 1
1 2
2 1
2 2
2 3

Cependant, je veux garder l'ordre de la 2ème colonne, comme ceci :

1 2
1 1
2 3
2 2
2 1

Est-ce possible avec la commande sort ?

Réponses (3)

68
68
68
2009-08-31 16:28:27 +0000

Essayez-le :

sort -s -n -k 1,1

Le -s désactive le tri de “dernier recours”, qui trie sur tout ce qui ne fait pas partie d'une clé spécifiée.

Le -k 1 ne signifie pas vraiment “ce champ et tout ce qui suit” dans le contexte du tri numérique, comme vous pouvez le voir si vous essayez de trier sur la deuxième colonne. Vous voyez simplement les liens rompus en allant au reste de la ligne. En général, cependant, vous devez spécifier -k 1,1 pour trier seulement sur le premier champ.

10
10
10
2012-10-16 13:59:28 +0000

Pour ne trier que sur la première colonne, vous devez le faire :

sort -n -s -k1,1

De Unix and Linux System Administration Handbook

sort accepte la spécification clé -k3 (plutôt que -k3,3), mais ne fait probablement pas ce que vous attendez. Sans le numéro du champ de terminaison, la clé de tri continue jusqu'à la fin de la ligne

2
2
2
2016-12-30 17:47:12 +0000

Aucune des réponses fournies ne me convient en général.

Les deux sort -s -k 2 file1 et sort -n -k1,1 font un tri supplémentaire avec ce fichier :

# cat file1
 3 3 5
 3 2 3
 1 4 7
 0 1 2
 3 2 1

J'ai juste eu à faire exactement la même chose et j'ai fini par utiliser une boucle de shell. Cette solution pourrait ne pas fonctionner correctement sur un très gros fichier car le fichier entier doit être lu pour chaque valeur unique dans la colonne triée.

Ici, le fichier est trié uniquement sur la colonne 2.

# awk '{print $2}' file1 | sort | uniq | while read index
do  
    awk -v var=$index '$2 == var { print $0}' file1 
done
 0 1 2
 3 2 3
 3 2 1
 3 3 5
 1 4 7