Jeg står overfor en stor fil med 4 kolonner. Jeg vil gjerne vise den sorterte filen i stdout basert på den tredje kolonnen:
cat myFile | sort -u -k3
Er det nok til å utføre trikset?
sort -k 3,3 myFile
vil vise filen sortert etter kolonnen 3rd, forutsatt at kolonnene er atskilt med sekvenser av blanktegn (ASCII SPC og TAB-tegn i POSIX/C-lokalet), i henhold til sorteringsrekkefølgen som er definert av det gjeldende lokalet.
Legg merke til at de ledende blanktegnene er inkludert i kolonnen (standard skilletegn er overgangen fra et ikke-blanktegn til et blanktegn), noe som kan utgjøre en forskjell i språk der mellomrom ikke ignoreres for sammenligningsformål, bruk -b
-alternativet for å ignorere de ledende blanktegnene.
Merk at det er helt uavhengig av skallet (alle skallene vil analysere den kommandolinjen på samme måte, skall har vanligvis ikke sort
-kommandoen innebygd).
-k 3
er å sortere på den delen av linjene som starter med 3rd kolonne (inkludert de ledende blanks). I C-lokalet, fordi mellomrom og tabulatortegn rangerer før alle utskrivbare tegn, vil det vanligvis gi deg samme resultat som -k 3,3
(unntatt for linjer som har et identisk tredje felt),
-u
er å beholde bare en av linjene hvis det er flere som sorterer identisk (det er der sorteringsnøkkelen sorterer det samme (det er ikke nødvendigvis det samme som å være lik)).
cat
er kommandoen for concatenate. Du trenger det ikke her.
Hvis kolonnene er adskilt av noe annet, trenger du -t
-alternativet for å angi skilletegn.
Gitt eksempelfil a
$ cat a
a c c c
a b ca d
a b c e
a b c d
Med -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
Linje 2 og 3 har samme tredje kolonne, men her er sorteringsnøkkelen fra tredje kolonne til slutten av linjen, så -u
beholder begge. ␠ca␠d
sorterer før ␠c␠c
fordi mellomrom ignoreres i det første passet i min locale, cad
sorterer før cc
.
$ sort -u -k 3,3 a
a b c d
a b c e
a b ca d
Ovenfor er bare én beholdt for de der den tredje kolonnen er ␠c
. Legg merke til hvordan den med ␠␠c
(2 ledende mellomrom) beholdes.
$ 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
Se hvordan rekkefølgen av a b c d
og a c c c
er byttet om. I det første tilfellet, fordi ␠c␠c
sorterer før ␠c␠d
, i det andre tilfellet fordi sorteringsnøkkelen er den samme (␠c
), setter den siste sammenligningen som sammenligner linjene i sin helhet a b c d
før 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
Når vi ignorerer de tomme feltene, er sorteringsnøkkelen for de tre første linjene den samme (c
), slik at de sorteres etter den siste sammenligningen.
$ 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
I C-lokalet sorterer ␠␠c
før ␠c
siden det bare er ett pass der tegn (da enkeltbytes) sorteres basert på kodepunktverdien (der mellomrom har lavere kodepunkt enn c
).
Hvis du forstår "kolonne" som i tekstfil (4. tegn), så ja, bør løsningen din fungere (eller til og med sort -u -k3 myFile
for å la sort
utføre litt minnebesparende magi med tilfeldig tilgang). Hvis du forstår " kolonne " som i database - en hel enhet med data etterfulgt av en separator og variabel kolonnebredde, trenger du noe mer fancy, for eksempel dette sorterer ls -l etter størrelse
ls -l |awk '{print $5 " " $0;}'| sort -n | cut -d " " -f 2-
(som er ekvivalent med trivielle ls -lS
, men tjener eksempelet fint).
sort -g -k column_number
er den rette kommandoen for å sortere en liste med numeriske tegn ved hjelp av en bestemt kolonne.