Sortare pe baza celei de-a treia coloane

Mă confrunt cu un fișier imens cu 4 coloane. Aș dori să afișez fișierul sortat în stdout pe baza celei de-a 3-a coloane:

cat myFile | sort -u -k3

Este suficient pentru a efectua trucul?

Soluția
sort -k 3,3 myFile

ar afișa fișierul sortat după coloana 3rd presupunând că coloanele sunt separate prin secvențe de spații libere (caractere ASCII SPC și TAB în limbajul local POSIX/C), în conformitate cu ordinea de sortare definită de limbajul local curent.

Rețineți că spațiile libere din față sunt incluse în coloană (separatorul implicit este tranziția de la un spațiu liber la un spațiu liber), ceea ce poate face o diferență în localele în care spațiile nu sunt ignorate în scopul comparării, utilizați opțiunea -b pentru a ignora spațiile libere din față.

Rețineți că este complet independent de shell (toate shell-urile ar analiza acea linie de comandă la fel, în general, shell-urile nu au încorporată comanda sort).

-k 3 este pentru a sorta pe porțiunea de linii care începe cu coloana 3rd (inclusiv spațiile libere din față). În limbajul local C, deoarece caracterele de spațiu și de tabulare se clasează înaintea tuturor caracterelor imprimabile, acest lucru vă va da în general același rezultat ca și -k 3,3 (cu excepția liniilor care au un al treilea câmp identic),

-u este pentru a reține doar una dintre linii dacă există mai multe linii care se sortează identic (adică atunci când cheia de sortare sortează la fel (ceea ce nu înseamnă neapărat că este sunt egale)).

cat este comanda pentru a concatenționa. Nu aveți nevoie de ea aici.

Dacă coloanele sunt separate de altceva, aveți nevoie de opțiunea -t pentru a specifica separatorul.

Fișierul de exemplu dat a

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

Cu -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

Liniile 2 și 3 au aceeași a treia coloană, dar aici cheia de sortare este de la a treia coloană până la sfârșitul liniei, așa că -u le păstrează pe ambele. ␠ca␠d se sortează înaintea lui ␠c␠c deoarece spațiile sunt ignorate în prima trecere în localitatea mea, cad se sortează înaintea lui cc.

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

Mai sus se reține doar una pentru cele în care a treia coloană este ␠c. Observați cum este reținută cea cu ␠␠c (2 spații înainte).

$ 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

Observați cum se inversează ordinea dintre a b c d și a c c c c. În primul caz, deoarece ␠c␠c se sortează înaintea lui ␠c␠d, în al doilea caz, deoarece cheia de sortare este aceeași (␠c), comparația de ultimă instanță care compară liniile în întregime pune a b c d înaintea lui a c 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

După ce ignorăm spațiile goale, cheia de sortare pentru primele 3 linii este aceeași (c), astfel încât acestea sunt sortate după comparația de ultimă instanță.

$ 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

În limbajul local C, ␠␠c se sortează înaintea lui ␠c, deoarece există o singură trecere acolo, unde caracterele (apoi octeți unici) se sortează în funcție de valoarea punctului de cod (unde spațiul are un punct de cod mai mic decât c).

Comentarii (7)

Dacă înțelegeți "column" ca fiind un fișier text (al 4-lea caracter), atunci da, soluția dvs. ar trebui să funcționeze (sau chiar sort -u -k3 myFile pentru a permite sort să efectueze unele magii de economisire a memoriei cu acces aleatoriu). Dacă înțelegeți "column" ca în baza de date - o întreagă entitate de date urmată de un separator și o lățime variabilă a coloanei, veți avea nevoie de ceva mai sofisticat, de exemplu, acest lucru sortează ls -l după mărime

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

(ceea ce este echivalent cu trivialul ls -lS, dar servește frumos exemplului).

Comentarii (2)
sort -g -k column_number 

este comanda corectă pentru a sorta orice listă cu caractere numerice folosind o anumită coloană

Comentarii (2)