Utilizzo di coreutils sort
, come posso ordinare numericamente in base a un valore esadecimale (campo)? Mi aspettavo qualcosa sulla falsariga di
sort -k3,3x file_to_sort
tuttavia, un tale x
non esiste.
Modifica:la migliore soluzione che ho trovato finora è:
{ echo ibase=16; cut -d' ' -f3 file_to_sort; } |
bc | paste -d: - file_to_sort | sort -t: -k1,1n | cut -d: -f2-
dove cut -d' ' -f3
isola il campo di ricerca (questo è -k3,3
— questo può variare, ovviamente) e bc
esegue la conversione in decimale (richiede esadecimale maiuscolo, senza 0x
prefisso, corrispondente al mio caso). Quindi unisco, ordino e divido le colonne.
Input minimo del campione:
5 hhf 25
3 ezh ae
1 hdh d12
2 ukr 9f
4 jjk 7
Output previsto (file ordinato per hex
terza colonna):
4 jjk 7
5 hhf 25
2 ukr 9f
3 ezh ae
1 hdh d12
Risposta accettata:
Una soluzione in perl
:
$ perl -anle '
push @h, [$F[-1],$_];
END {
print for map { $_->[0] }
sort { $a->[1] <=> $b->[1] }
map { [$_->[1],hex($_->[0])] } @h;
}
' file
4 jjk 7
5 hhf 25
2 ukr 9f
3 ezh ae
1 hdh d12
Spiegazione
-
Durante l'elaborazione del file, creiamo un array di array
@h
, ciascuno dei suoi elementi è un riferimento di matrice[$F[-1],$_]
, con il primo elemento è il valore esadecimale da confrontare e il secondo elemento è l'intera riga. -
In
END
blocco, usiamo la trasformata di Schwartz:-
Con ogni elemento di
@h
, crea un array anonimo, contiene l'intera riga ($_->[1]
il secondo elemento di ogni riferimento di matrice in@h
) e il valore esadecimale per confrontarehex($_->[0])]
-
Ordina sopra la base dell'array sul valore esadecimale
$a->[1] <=> $b->[1]
-
Ottieni il primo elemento di ogni riferimento di matrice nell'array ordinato
map { $_->[0] }
quindi stampa il risultato.
-
Aggiorna
Con il suggerimento di @Joseph R, senza usare Schwartzian Transform:
$ perl -anle '
push @h, [hex($F[-1]),$_];
END {
print $_->[1] for
sort { $a->[0] <=> $b->[0] } @h;
}
' file
Aggiorna 2
Dopo aver letto il commento di Stefan, penso che questo possa chiamare direct
:
$ perl -e '
print sort {hex((split(/s+/,$a))[-1]) <=> hex((split(/s+/,$b))[-1])} <>;
' file
4 jjk 7
5 hhf 25
2 ukr 9f
3 ezh ae
1 hdh d12