utiliser le tri GNU pour trier par une seule clé / empêcher le tri indésirable des autres clés

9

J'ai un fichier qui contient des données déjà ordonnées et je voudrais réorganiser le fichier en fonction des valeurs d'une clé, sans détruire l'ordre des données des autres clés.

Comment empêcher le tri GNU d'effectuer le tri des lignes en fonction des valeurs des clés que je n'ai pas spécifiées, ou comment spécifier au tri GNU pour ignorer une plage de clés lors du tri?

Fichier data.txt:

1 Don't
2 C 
1 Sort
2 B
1 Me
2 A

Production attendue:

1 Don't
1 Sort
1 Me
2 C
2 B
2 A

Commander:

sort -k 1,1 <data.txt

Résultat: tri indésirable que je n'ai pas demandé:

1 Don't
1 Me
1 Sort
2 A
2 B
2 C
Wil
la source

Réponses:

21

Vous avez besoin d'un tri stable . De man sort:

-s, --stable
       stabilize sort by disabling last-resort comparison

à savoir:

$ sort -sk 1,1 <data.txt
1 Don't
1 Sort
1 Me
2 C 
2 B
2 A

Notez que vous voulez probablement aussi un -nou --numeric-sortsi votre clé est numérique (par exemple, vous pouvez obtenir des résultats inattendus en comparant 10 à 2 avec l'ordre de tri par défaut - lexical). Dans ce cas, il s'agit simplement de faire:

sort -sn <data.txt

Pas besoin d'extraire le premier champ car l'interprétation numérique de la ligne entière sera la même que celle du premier champ.

tournevis
la source
J'ai lu la documentation mais la définition correcte de "stable" a échappé à mon attention. Merci pour la réponse rapide, concise et bien citée. La première clé des données réelles est une chaîne localisée, donc le numérique ne fonctionnerait pas pour moi.
Wil
4

Pour les sortimplémentations (non GNU) qui n'ont pas d' -soption, vous pouvez toujours faire:

<data.txt awk '{print NR "\t" $0}' | sort -n -k 2,2 -k 1,1 | cut -f 2-

Autrement dit, ajoutez le numéro de ligne pour en faire la deuxième clé de tri et supprimez-le ensuite.

Stéphane Chazelas
la source