web-dev-qa-db-fra.com

Tri basé sur la troisième colonne

Je fais face à un énorme fichier à 4 colonnes. Je voudrais afficher le fichier trié dans stdout en fonction de sa 3ème colonne:

cat myFile | sort -u -k3

Est-ce suffisant pour exécuter l'astuce?

151
user1058398
sort -k 3,3 myFile

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

Notez que les premiers blancs sont inclus dans la colonne (le séparateur par défaut est la transition d'un non-blanc à un blanc), ce qui peut faire la différence dans les paramètres régionaux où les espaces ne sont pas ignorés à des fins de comparaison, utilisez le -b option pour ignorer les blancs en tête.

Notez qu'il est complètement indépendant du Shell (tous les shells analyseraient la même ligne de commande de la même manière, les shells n'ont généralement pas la commande sort intégrée).

-k 3 consiste à trier la partie des lignes commençant par le 3rd (y compris les premiers blancs). Dans les paramètres régionaux C, car les caractères d'espace et de tabulation se classent 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 conserver qu'une seule des lignes s'il y en a plusieurs qui trient de manière identique (c'est là que la clé de tri trie la même chose (ce n'est pas nécessairement la même chose que étant égal )).

cat est la commande à con cat enate. Vous n'en avez pas besoin ici.

Si les colonnes sont séparées par autre chose, vous avez besoin du -t option pour spécifier le séparateur.

Exemple de fichier donné 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 va de la troisième colonne à la fin de la ligne, donc -u conserve les deux. ␠ca␠d tri avant ␠c␠c car les espaces sont ignorés lors de la première passe dans mes paramètres régionaux, cad trie avant cc.

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

Au-dessus, une seule est conservée pour celles où la 3e colonne est ␠c. Notez comment celui avec ␠␠c (2 espaces de début) est conservé.

$ 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 et a c c c sont inversés. Dans le premier cas, car ␠c␠c tri avant ␠c␠d, dans le second cas car la clé de tri est la même (␠c), la comparaison de dernier recours qui compare les lignes en entier met a b c d avant a 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 que nous ignorons les blancs, la clé de tri pour les 3 premières lignes est la même (c), ils sont donc triés 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 l'environnement local C, ␠␠c tri avant ␠c car il n'y a qu'une seule passe où les caractères (puis les octets simples) trient en fonction de leur valeur de point de code (où l'espace a un point de code inférieur à c).

186
Stéphane Chazelas
sort -t : -k 3 filename

lorsque votre délimiteur est : et vous devez trier le fichier filename par le 3rd champ.

5
wiem fourati

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

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

(ce qui équivaut à trivial ls -lS mais sert bien l'exemple.)

4
SF.
sort -g -k column_number 

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

3

Vous pouvez utiliser l'awk bibliothèque Velour :

#!/usr/local/bin/velour -f
{
  q[NR] = $3
  z[NR] = $0
}
END {
  a_sort_by(q, z)
  io_puts(q)
}
1
Steven Penny
$ sort -k 1.3,1.3 myfile

Triera votre fichier myfile sur la troisième colonne si votre fichier n'a pas de séparateur.

$ cat myfile 
ax5aa 
aa3ya 
fg7ds 
pp0dd 
aa1bb

$ sort -k 1.3,1.3 myfile 
pp0dd 
aa1bb
aa3ya 
ax5aa 
fg7ds 

page de manuel de tri:

[...] -k, --key = POS1 [ POS2] démarre une clé à POS1 (origine 1), termine-la à POS2 (fin de ligne par défaut) [...] POS est F [ .C] [OPTS], où F est le numéro de champ et C la position des caractères dans le champ; les deux sont d'origine 1. Si ni -t ni -b n'est en vigueur, les caractères d'un champ sont comptés à partir du début du précédent blanc. OPTS est une ou plusieurs options de commande à une seule lettre, qui remplacent les options de commande globales pour cette clé. Si aucune clé n'est donnée, utilisez la ligne entière comme clé.

Avec --key = 1.3,1.3, vous avez dit qu'il n'y avait qu'un seul champ (toute la ligne) et que vous comparez la position du troisième caractère de ce champ.

0
Franck