Windows XP Windows 7 Windows 2003 Windows Vista Windows 綜合教學 Linux 系統教學
Windows 10 Windows 8 Windows 2008 Windows NT Windows Server 電腦軟體教學
您现在的位置: Windows教程網 >> Windows教程 >  >> Linux 系統教學 >> Linux 教學

awk 陣列排序四大法:內建函數、管線 sort、自定義函數與索引遍歷完整對比

編輯:Linux 教學

awk 陣列為關聯陣列,for (k in arr) 遍歷順序不確定。本文詳解四種排序輸出方案,含效能分析與適用場景建議。

預設無序輸出

awk 'BEGIN{info="this is a test"; split(info,a," "); for(k in a) print k,a[k]}'
# 輸出順序不定:4 test / 1 this / 2 is / 3 a

方法一:索引遍歷 (適用連續數字索引)

awk 'BEGIN{info="this is a test"; n=split(info,a," "); for(i=1;i<=n;i++) print i,a[i]}'
# 輸出:1 this / 2 is / 3 a / 4 test

限制:索引必須為 1..n 連續整數。

方法二:內建函數 asort / asorti (gawk 3.1+)

asort:按值排序,重建 1..n 索引

awk 'BEGIN{a[100]=100; a[2]=224; a[3]=34; n=asort(a,b); for(i=1;i<=n;i++) print i,b[i]}'
# 輸出:1 34 / 2 100 / 3 224 (原鍵值 100/2/3 遺失)

asorti:按鍵排序,結果存新陣列

awk 'BEGIN{a["d"]=100; a["a"]=224; a["c"]=34; n=asorti(a,b); for(i=1;i<=n;i++) print i,b[i],a[b[i]]}'
# 輸出:1 a 224 / 2 c 34 / 3 d 100 (按鍵字典序)

注意:asort/asorti 僅支援 gawk (GNU awk),mawk/nawk 不支援。

方法三:管線外部 sort (通用、大數據首選)

按值數值降序

awk 'BEGIN{a[100]=100; a[2]=224; a[3]=34; for(i in a) print i,a[i] | "sort -rn -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 -rn -k1"}'
# 輸出:100 100 / 3 34 / 2 224

按鍵字典序

awk 'BEGIN{a["d"]=100; a["a"]=224; a["c"]=34; for(i in a) print i,a[i] | "sort -k1"}'
# 輸出:a 224 / c 34 / d 100

優點:利用系統 sort 高效能、支援海量資料、語法簡潔。
缺點:啟動子進程、需格式化輸出供 sort 解析。

方法四:自定義氣泡排序函數 (無外部依賴、小數據最快)

function sortArr(arr, key, datatype,  tarr, splitseq, alen, k, m, n, tm, tn, tnum) {
    if (key !~ /^[12]$/) return 0
    splitseq = "%%"
    for (k in arr) tarr[++alen] = k splitseq arr[k]
    for (m=1; m<=alen; m++) {
        for (n=1; n<=alen-m; n++) {
            split(tarr[m], tm, splitseq)
            split(tarr[n+1], tn, splitseq)
            if (datatype == 1) {          # 數值比較
                if (tm[key]+0 < tn[key]+0) { tnum=tarr[m]; tarr[m]=tarr[n+1]; tarr[n+1]=tnum }
            } else {                      # 字串比較
                if (tm[key] "" < tn[key] "") { tnum=tarr[m]; tarr[m]=tarr[n+1]; tarr[n+1]=tnum }
            }
        }
    }
    return alen
}

# 使用範例:按鍵字典序降序
awk 'BEGIN{
    a["a"]=100; a["b"]=110; a["c"]=10
    n=sortArr(a, 2, 2)  # key=2(值), datatype=2(字串)
    for(i=1;i<=n;i++) { split(tarr[i],ta,"%%"); print i,ta[1],ta[2] }
}'
# 輸出:1 b 110 / 2 a 100 / 3 c 10

效能與選型建議

方法適用資料量相依性鍵值保留速度
索引遍歷小、連續索引無完整最快
asort/asorti中、需 gawkgawk 3.1+asorti 保留快
管線 sort大、跨平台系統 sort完整中 (進程開銷)
自定義函數小、無外部依賴無完整中 (O(n²))

實務上:<1萬筆用 asorti/管線 sort,>10萬筆必用管線 sort,嵌入式無 sort 指令才寫自定義函數。

Copyright © Windows教程網 All Rights Reserved