Anche se non lo consiglierei (data la relativa semplicità di sort
eseguire il piping del risultato tramite un comando esterno ), puoi farlo almeno con le versioni recenti di GNU awk (almeno 4.0 IIRC), come descritto in Ordinamento di valori di array e indici con gawk
Ecco come potresti implementarlo, supponendo che tu abbia i dati in un array associativo in cui si trova l'indice Firstname Lastname
. Per prima cosa devi definire una funzione di confronto personalizzata che divide l'indice, poi confronta prima Lastname
(come un pareggio) ad Firstname
es.
function mycmp(ia, va, ib, vb, sa, sb) {
if(split(toupper(ia), sa) && split(toupper(ib), sb)) {
if(sa[2] < sb[2]) return -1;
else if (sa[2] > sb[2]) return 1;
else {
# compare first names
if(sa[1] < sb[1]) return -1;
else if (sa[1] > sb[1]) return 1;
else return 0;
}
}
else return 0;
}
Ora puoi usare il PROCINFO["sorted_in"]
metodo di ordinamento degli array menzionato nei commenti di @zwets
PROCINFO["sorted_in"] = "mycmp";
for(i in a) print i, a[i];
Mettendolo insieme
#!/usr/bin/gawk -f
function mycmp(ia, va, ib, vb, sa, sb) {
if(split(toupper(ia), sa) && split(toupper(ib), sb)) {
if(sa[2] < sb[2]) return -1;
else if (sa[2] > sb[2]) return 1;
else {
# compare first names
if(sa[1] < sb[1]) return -1;
else if (sa[1] > sb[1]) return 1;
else return 0;
}
}
else return 0;
}
{
a[$1" "$2] = $3;
}
END {
PROCINFO["sorted_in"] = "mycmp";
for(i in a) print i, a[i];
}
test:
$ ./namesort.awk yourfile
Kobe Bryant 24
Kevin Durant 35
Blake Griffin 32
Lebron James 23
Dikembe Mutumbo 55
Nelle versioni precedenti o precedenti di awk, la soluzione migliore potrebbe essere quella di archiviare i dati indicizzati Lastname Firstname
invece, ordinare con il convenzionale asorti
, quindi dividere e scambiare i campi degli indici mentre si attraversa l'array per stamparlo:
awk '
{a[$2" "$1]=$3}
END {
n=asorti(a,b); for (i=1;i<=n;i++) {split(b[i],s); print s[2], s[1], a[b[i]]}
}' yourfile
x
, quindi impostarePROCINFO["sorted_in"]
su un valore criptico, quindi emettere l'array. Non ci andrei.