Trier en fonction de la troisième colonne


132

Je suis confronté à un énorme fichier de 4 colonnes. Je voudrais afficher le fichier trié dans stdout basé sur sa 3ème colonne:

cat myFile | sort -u -k3

Est-ce suffisant pour exécuter le tour?


4
Notez que vous pouvez écrire ceci en tant que sort -u -k3 < myFile.
gerrit

6
Comme sort -u -k3 myFile, même
Sebastian Graf

Réponses:


168
sort -k 3,3 myFile

afficherait le fichier triés par la 3 ème colonne en supposant que les colonnes sont séparées par des séquences d'ébauches (SPC ASCII et les caractères de tabulation dans la locale POSIX / C), selon l'ordre de tri défini par la localisation en cours.

Notez que les blancs qui précèdent sont inclus dans la colonne (le séparateur par défaut est la transition d’un non-blanc à un blanc), ce qui peut faire une différence dans les locales où les espaces ne sont pas ignorés à des fins de comparaison. Utilisez cette -boption pour ignorer les premiers blancs.

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

-k 3est de trier sur la partie des lignes commençant par la 3 ème colonne (y compris les blancs en tête). Dans les paramètres régionaux C, étant donné que l'espace et les caractères de tabulation sont classés avant tous les caractères imprimables, vous obtiendrez généralement le même résultat que -k 3,3(sauf pour les lignes ayant un troisième champ identique),

-uest de ne conserver qu'une seule des lignes s'il y en a plusieurs qui trient de manière identique (c'est-à-dire où la clé de tri trie de la même manière (ce n'est pas nécessairement la même chose qu'être égal )).

catest la commande pour con cat enate. Vous n'en avez pas besoin ici.

Si les colonnes sont séparées par quelque chose d'autre, vous avez besoin de l' -toption 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 va de la troisième colonne à la fin de la ligne, donc -uconserve les deux. ␠ca␠dtrie avant ␠c␠cparce que les espaces sont ignorés lors de la première passe dans ma locale, cadtrie avant cc.

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

Au-dessus, un seul est retenu pour ceux où la 3ème 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 det a 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 complètes passe a b c davant 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 avons ignoré les blancs, la clé de tri pour les 3 premières lignes est la même ( c), elles sont donc triées selon 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 les paramètres régionaux C, les ␠␠ctris avant, ␠ccar il n’ya qu’un seul passage 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 à celui c).


les colonnes sont blankséparées et peuvent inclure d'autres caractères, en plus de l'espace et de la tabulation, en fonction des paramètres régionaux.
Jfs

1
Nice, +1. Pourriez-vous expliquer ce que le 3,3fait? Pourquoi pas juste 3?
terdon

@terdon, voir la description détaillée avec des exemples.
Stéphane Chazelas

@JFSebastian, vous avez raison, réponse mise à jour.
Stéphane Chazelas

Ah, pour que le tri soit seulement le 3, pas le reste de la ligne, merci.
terdon

4

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 myFilepermettre de sortréaliser des opérations magiques 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 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 est équivalent à trivial ls -lSmais sert bien l'exemple.)


5
Non, par défaut trier les colonnes sont vides séparés, ils ne sont pas des colonnes de caractères, pour trier la colonne 3 de caractères, la syntaxe serait: sort -k 1.3,1.3. ls -l | sort -k5,5ntrier sur la taille.
Stéphane Chazelas

La awksolution est exactement ce dont j'avais besoin - facilement modifiable pour répondre aux exigences de tri complexes
jchook

2
sort -g -k column_number 

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


1
L'utilisation de -k étant déjà assez bien couverte , il serait utile que vous expliquiez en quoi cette commande est différente ou meilleure. Peut-être pourriez-vous également inclure les numéros de colonne réels pour répondre à la question du PO.
Jeff Schaller

Cela m'a amené à utiliser les pages de manuel: p "-g, --general-numeric-sort, compare selon la valeur numérique générale", ce qui était ce dont j'avais besoin dans mon cas.
Joels


0
$ sort -k 1.3,1.3 myfile

Triera votre fichier myfile sur la troisième colonne si votre fichier ne contient 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 sorte:

[...] -k, --key = POS1 [, POS2] commence une clé sur POS1 (origine 1), la termine sur POS2 (fin de ligne par défaut) [...] POS est F [.C] [ OPTS], où F est le numéro du champ et C la position du caractère dans le champ; les deux sont d'origine 1. Si ni -t ni -b ne sont en vigueur, les caractères d'un champ sont comptés à partir du début de l'espace précédent. OPTS est une ou plusieurs options de classement à une lettre, qui remplacent les options de classement 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 (la ligne entière) et que vous compariez la position du troisième caractère de ce champ.

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.