awk 內置關聯數組無序存儲,排序輸出需特定技巧。本文系統梳理 內置函數法、管道外部排序法、自定義函數法 三大方案,附帶版本兼容性說明與性能對比。
awk 'BEGIN{info="this is a test"; split(info,tA," "); for(k in tA) print k, tA[k]}'
# 輸出順序不可預測:
4 test
1 this
2 is
3 a
awk 'BEGIN{
a[100]=100; a[2]=224; a[3]=34;
slen=asort(a, tA);
for(i=1;i<=slen;i++) print i, tA[i]
}'
# 輸出(值升序,原鍵值丟失):
1 34
2 100
3 224
awk 'BEGIN{
a["d"]=100; a["a"]=224; a["c"]=34;
slen=asorti(a, tA);
for(i=1;i<=slen;i++) print i, tA[i], a[tA[i]]
}'
# 輸出(鍵字典序):
1 a 224
2 c 34
3 d 100
awk 'BEGIN{
a[100]=100; a[2]=224; a[3]=34;
for(i in a) print i, a[i] | "sort -r -n -k2"
}'
# 輸出:
2 224
100 100
3 34
awk 'BEGIN{
a[100]=100; a[2]=224; a[3]=34;
for(i in a) print i, a[i] | "sort -r -n -k1"
}'
# 輸出:
100 100
3 34
2 224
參數解析:-r 逆序、-n 數值排序、-k2 按第 2 列排序
awk 'function qsort(arr, left, right, i, last) {
if (left >= right) return
swap(arr, left, left+int((right-left+1)*rand()))
last = left
for (i=left+1; i<=right; i++)
if (arr[i] < arr[left]) swap(arr, ++last, i)
swap(arr, left, last)
qsort(arr, left, last-1)
qsort(arr, last+1, right)
}
function swap(arr, i, j, t) { t=arr[i]; arr[i]=arr[j]; arr[j]=t }
BEGIN{
a[1]=3; a[2]=1; a[3]=2; n=3
qsort(a, 1, n)
for(i=1;i<=n;i++) print a[i]
}'
| 場景 | 推薦方案 | 理由 |
|---|---|---|
| 現代系統、需高性能 | asort/asorti | 內置 C 實現,速度最快 |
| 舊版 awk、複雜排序邏輯 | 管道 sort | 利用成熟 sort 工具,功能最全 |
| 教學、特殊數據結構 | 自定義函數 | 理解算法原理,可擴展性強 |
awk --version | head -1
# GNU Awk 5.1.0, API: 3.0 # 支持 asort/asorti
# mawk 1.3.4 # 不支持
掌握三大排序方案,應對各類 awk 數組排序需求游刃有餘。