Come ordinare questo output 1,10,11..2
A volte ho bisogno di aggiungere più disco a un database; per questo, ho bisogno di elencare i dischi per vedere quali dischi esistono già.
Il problema è che l'output è sempre ordinato come 1,10,11,12 ... 2,20,21 ... 3 ecc.
Come posso ordinare questo output nel modo desiderato? Un semplice sort
non funziona; Ho anche provato a usare sort -t.. -k.. -n
.
Esempio di ciò che devo ordinare:
[root@server1 ~]# oracleasm listdisks
DATA1
DATA10
DATA11
DATA12
DATA2
DATA3
DATA4
DATA5
DATA6
DATA7
DATA8
DATA9
FRA1
FRA10
FRA11
FRA2
FRA3
..
OCR1
OCR2
OCR3
....
Come vorrei vedere l'output:
DATA1
DATA2
DATA3
DATA4
DATA5
DATA6
DATA7
DATA8
DATA9
DATA10
DATA11
DATA12
FRA1
FRA2
FRA3
..
..
FRA10
FRA11
..
OCR1
OCR2
OCR3
....
Risposte
La soluzione migliore è passare a GNU sort
, con sort
l' --version-sort
opzione GNU abilitata
così sarebbe oracleasm listdisks | sort --version-sort
Dalla pagina delle informazioni
--version-sort’
Sort by version name and number. It behaves like a standard sort,
except that each sequence of decimal digits is treated numerically
as an index/version number. (*Note Details about version sort::.)
Sul tuo input mi dà
DATA1
DATA2
DATA3
DATA4
DATA5
DATA6
DATA7
DATA8
DATA9
DATA10
DATA11
DATA12
FRA1
FRA2
FRA3
FRA10
FRA11
OCR1
OCR2
OCR3
Se sort --version-sort
non è disponibile, dividere in 2 campi: campo 1 = non cifre iniziali e campo 2 = numero intero e stampare i campi con TAB tra di loro. Quindi utilizzare sort
su 2 campi delimitati da TAB, quindi rimuovere il TAB. Collegare tramite tubi per evitare overhead di I / O. Ecco un esempio con una fetta minima dei dati dall'OP, più alcuni record aggiuntivi:
echo 1 10 2 11 DATA DATA1 DATA10 DATA11 DATA2 FRA FRA1 FRA10 FRA11 FRA2 | \
xargs -n1 | \
perl -lne 'print join "\t", /(\D*)(\d*)/' | \
sort -k1,1 -k2,2n | \
perl -pe 's/\t//'
Stampe:
1
10
11
2
DATA
DATA1
DATA2
DATA10
DATA11
FRA
FRA1
FRA2
FRA10
FRA11
DETTAGLI:
Gli one-liner di perl usano questi flag della riga di comando
-e
:: dice a Perl di cercare il codice in-line, invece che in un file.
-n
: scorre sull'input una riga alla volta, assegnandola per $_
impostazione predefinita.
-l
: elimina il separatore di riga di input ( "\n"
su * NIX per impostazione predefinita) prima di eseguire il codice in linea e aggiungilo durante la stampa.
-p
: uguale a -n
, ma anche print
la riga alla fine di ogni ciclo (elimina esplicito print
).
All'interno della prima riga, \d
è presente qualsiasi cifra (0-9) e \D
qualsiasi non cifra. Ciascuno di questi modelli viene ripetuto 0 o più volte (utilizzando *
). I due modelli vengono catturati utilizzando le parentesi e restituiti come un LIST
di due campi, che vengono uniti su una TAB e stampati.
Il secondo one-liner Perl rimuove semplicemente il primo TAB viene trovato senza nulla (stringa vuota) e stampa la riga.
Per sort
su 2 campi, vengono utilizzate queste opzioni -k1,1
:: ordina sul campo 1 ASCIIbeticamente. Quindi::
-k2,2n
se il campo 1 è lo stesso, ordinare il campo 2 numericamente ( -n
opzione).
Notare che il numero del campo viene ripetuto due volte (ad es. 1,1
), Per impedire l'ordinamento sul resto della riga e limitare l'ordinamento solo a questo numero di colonna.