Ordinamento di più chiavi con ordinamento Unix

Ho file potenzialmente grandi che devono essere ordinati per chiavi 1-n. Alcune di queste chiavi potrebbero essere numeriche e alcune potrebbero non esserlo. Questo è un file colonnare a larghezza fissa, quindi non ci sono delimitatori.

C’è un buon modo per farlo con Unix sort? Con una chiave è semplice come usare ‘-n’. Ho letto la pagina man e ho cercato Google brevemente, ma non ho trovato un buon esempio. Come potrei fare per realizzare questo?

Nota: ho escluso Perl a causa delle dimensioni del file. Sarebbe un’ultima risorsa.

Utilizzare l’opzione -k (o --key=POS1[,POS2] ). Può apparire più volte e ogni chiave può avere opzioni globali (come n per ordinamento numerico)

Fai attenzione però:

Se si desidera ordinare il file principalmente dal campo 3 e in secondo luogo dal campo 2 non si desidera questo:

 sort -k 3 -k 2 < inputfile 

lo vuoi invece:

 sort -k 3,3 -k 2,2 < inputfile 

Il primo ordina il file in base alla stringa dall'inizio del campo 3 alla fine della riga (che è potenzialmente univoca).

 -k, --key=POS1[,POS2] start a key at POS1 (origin 1), end it at POS2 (default end of line) 

L’opzione -k è ciò che vuoi.

 -k 1.4,1.5n -k 1.14,1.15n 

Userebbe le posizioni dei caratteri 4-5 nel primo campo (è tutto un campo per larghezza fissa) e ordinerà numericamente come prima chiave.

La seconda chiave sarebbe anche i caratteri 14-15 nel primo campo.

(modificare)

Esempio (tutto quello che ho è DOS / cygwin a portata di mano):

 dir | \cygwin\bin\sort.exe -k 1.4,1.5n -k 1.40,1.60r 

per i dati:

 12/10/2008 01:10 PM 1,564,990 outfile.txt 

Ordina l’elenco delle directory in base al numero del mese (pos 4-5) numericamente e quindi in base al nome del file (pos 40-60) al contrario. Poiché non ci sono tabs, è tutto il campo 1 da ordinare.

Ecco uno per ordinare varie colonne in un file CSV per ordine numerico e dizionario, colonne 5 e dopo come ordine di dizionario

 ~/test>sort -t, -k1,1n -k2,2n -k3,3d -k4,4n -k5d sort.csv 1,10,b,22,Ga 2,2,b,20,F 2,2,b,22,Ga 2,2,c,19,Ga 2,2,c,19,Gb,hi 2,2,c,19,Gb,hj 2,3,a,9,C ~/test>cat sort.csv 2,3,a,9,C 2,2,b,20,F 2,2,c,19,Gb,hj 2,2,c,19,Gb,hi 2,2,c,19,Ga 2,2,b,22,Ga 1,10,b,22,Ga 

Si noti che -k1,1n significa numerico che inizia alla colonna 1 e termina alla colonna 1. Se avessi fatto sotto, avrebbe concatenato la colonna 1 e 2 facendo 1,10 ordinati come 110

 ~/test>sort -t, -k1,2n -k3,3 -k4,4n -k5d sort.csv 2,2,b,20,F 2,2,b,22,Ga 2,2,c,19,Ga 2,2,c,19,Gb,hi 2,2,c,19,Gb,hj 2,3,a,9,C 1,10,b,22,Ga 

Credo nel tuo caso qualcosa del genere

 sort [email protected] -k1.1,1.4 -k1.5,1.7 ...  

funzionerà meglio @ è il separatore di campo, assicurati che sia un personaggio che non appare da nessuna parte. allora il tuo input è considerato come composto da una colonna.

Modifica: apparentemente Clintp ha già dato una risposta simile, mi dispiace. Come sottolinea, i flag "n" e "r" possono essere aggiunti a ogni opzione -k .....

Si noti che è anche ansible che si desideri stabilizzare l’ordinamento con l’ -s , in modo che anche le righe con uguali livelli mantengano l’ordine relativo originale nell’output.

Voglio solo aggiungere alcuni suggerimenti, quando si utilizza l’ordinamento, fare attenzione alle impostazioni internazionali che influiscono sull’ordine del confronto delle chiavi. Di solito uso LC_ALL = C in modo esplicito per rendere il locale ciò che voglio.