Trier sur la base de la troisième colonne

Je suis confronté à un énorme fichier à 4 colonnes. J'aimerais afficher le fichier trié dans stdout en fonction de sa 3ème colonne :

cat myFile | sort -u -k3

Est-ce suffisant pour réaliser l'exploit ?

Solution
sort -k 3,3 myFile

affiche le fichier trié par la colonne 3rd en supposant que les colonnes sont séparées par des séquences de blancs (caractères ASCII SPC et TAB dans la locale POSIX/C), selon l'ordre de tri défini par la locale courante.

Notez que les blancs de tête sont inclus dans la colonne (le séparateur par défaut est la transition entre un non-blanc et un blanc), ce qui peut faire une différence dans les locales où les espaces ne sont pas ignorés pour la comparaison, utilisez l'option -b pour ignorer les blancs de tête.

Notez que cela est complètement indépendant de l'interpréteur de commandes (tous les interpréteurs de commandes analyseront cette ligne de commande de la même manière, les interpréteurs de commandes n'ont généralement pas la commande sort intégrée).

-k 3 permet de trier sur la partie des lignes commençant par la colonne 3rd (y compris les blancs de tête). Dans la locale C, comme les caractères d'espacement et de tabulation se placent avant tous les caractères imprimables, cela vous donnera généralement le même résultat que -k 3,3 (sauf pour les lignes qui ont un troisième champ identique),

-u consiste à ne retenir qu'une seule des lignes s'il y en a plusieurs qui se trient de manière identique (c'est-à-dire lorsque la clé de tri trie de la même manière (ce qui n'est pas forcément la même chose que être égal)).

cat est la commande pour concatenate. Vous n'en avez pas besoin ici.

Si les colonnes sont séparées par quelque chose d'autre, vous avez besoin de l'option -t pour spécifier le séparateur.

Exemple de fichier a

$ cat a
a c c c
a b ca d
a b  c e
a b c d

Avec -u -k 3 :

$ echo $LANG
en_GB.UTF-8

$ sort -u -k 3 a
a b ca d
a c c c
a b c d
a b  c e

Les lignes 2 et 3 ont la même troisième colonne, mais ici la clé de tri est de la troisième colonne à la fin de la ligne, donc -u conserve les deux. ␠ca␠d trie avant ␠c␠c car les espaces sont ignorés au premier passage dans ma locale, cad trie avant cc.

$ sort -u -k 3,3 a
a b c d
a b  c e
a b ca d

Ci-dessus, un seul est retenu pour ceux où la 3ème colonne est ␠c. Notez comment celui avec ␠␠c (2 espaces en tête) est retenu.

$ sort -k 3 a
a b ca d
a c c c
a b c d
a b  c e
$ sort -k 3,3 a
a b c d
a c c c
a b  c e
a b ca d

Voyez comment l'ordre de a b c d' eta c c cest inversé. Dans le premier cas, parce que␠c␠ctrie avant␠c␠d, dans le second cas parce que la clé de tri est la même (␠c), la comparaison de dernier recours qui compare les lignes en entier meta b c davanta c c c`.

$ sort -b -k 3,3 a
a b c d
a b  c e
a c c c
a b ca d

Une fois les blancs ignorés, la clé de tri des 3 premières lignes est la même (c), elles sont donc triées par la comparaison de dernier recours.

$ LC_ALL=C sort -k 3 a
a b  c e
a c c c
a b c d
a b ca d
$ LC_ALL=C sort -k 3,3 a
a b  c e
a b c d
a c c c
a b ca d

Dans la locale C, ␠␠c trie avant ␠c car il n'y a qu'un seul passage là où les caractères (puis les octets simples) sont triés en fonction de leur valeur de point de code (où l'espace a un point de code inférieur à c).

Commentaires (7)

Si vous comprenez "colonne" comme un fichier texte (4ème caractère), alors oui, votre solution devrait fonctionner (ou même sort -u -k3 monFichier pour permettre à sort de faire des économies de mémoire avec les accès aléatoires). Si vous comprenez "colonne" comme dans une base de données - une entité entière de données suivie d'un séparateur, et une largeur de colonne variable, vous aurez besoin de quelque chose de plus sophistiqué, par exemple ceci trie ls -l par taille

      ls -l |awk '{print $5 " " $0;}'| sort -n | cut -d " " -f 2-

(ce qui est équivalent au trivial ls -lS mais sert bien l'exemple).

Commentaires (2)
sort -g -k column_number 

est la bonne commande pour trier toute liste ayant des caractères numériques en utilisant une colonne spécifique.

Commentaires (2)