Mặc dù tôi không khuyến nghị điều đó (với sự đơn giản tương đối của đường ống kết quả thông qua sort
lệnh bên ngoài ), bạn có thể thực hiện điều này ít nhất với các phiên bản gần đây của GNU awk (ít nhất là 4.0 IIRC), như được mô tả tại Sắp xếp các giá trị và chỉ số mảng với gawk
Đây là cách bạn có thể thực hiện nó, giả sử bạn có dữ liệu trong một mảng kết hợp trong đó chỉ mục Firstname Lastname
. Trước tiên, bạn cần xác định chức năng so sánh tùy chỉnh phân tách chỉ mục, trước tiên so sánh Lastname
sau đó (dưới dạng ngắt kết nối) trên Firstname
ví dụ:
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;
}
Bây giờ bạn có thể sử dụng PROCINFO["sorted_in"]
phương pháp sắp xếp mảng được đề cập trong các nhận xét của @zwets
PROCINFO["sorted_in"] = "mycmp";
for(i in a) print i, a[i];
Đặt nó lại với nhau
#!/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];
}
Kiểm tra:
$ ./namesort.awk yourfile
Kobe Bryant 24
Kevin Durant 35
Blake Griffin 32
Lebron James 23
Dikembe Mutumbo 55
Trong các phiên bản awk ít hơn hoặc cũ hơn, cách tốt nhất của bạn có thể là lưu trữ dữ liệu được lập chỉ mục Lastname Firstname
thay vào đó, sắp xếp theo thông thường asorti
, sau đó phân tách và trao đổi các trường của các chỉ mục khi bạn duyệt qua mảng để in:
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
, sau đó đặt thànhPROCINFO["sorted_in"]
giá trị mật mã, sau đó xuất mảng. Tôi sẽ không đến đó.