簡體   English   中英

如何使用bash計算文件中一行的出現次數? (有加分)

[英]How can I count ocurrences of a line in a file using bash? (with a plus)

這將是輸入

a b 125
a b 358
d t 485
d f 859
d t 789
a t 154

這將是輸出

2 a b 125
2 d t 485
1 d f 859
1 a t 154

重要提示:請注意,我需要做的是以下內容:

1 - 計算連接的前 2 列的出現次數。 例如:

a b 125
a b 358

這將是序列ab 的2 次出現。

2 - 保留每個序列的 id(第 3 列)的第一次出現。 例如:

a b 125
a b 358

在這種情況下,我想輸出2 ab 125

如果必須保留所需的輸出順序,則可以使用awk和 3-arrays 來保存看到前兩個字段的次數(數組a ),該數組保留遇到前兩個字段的順序(數組b ),最后是一個將前兩個字段與第三個字段(數組c )的第一個看到的字段進行映射的數組:

awk -v n=1 '{ a[$1" "$2]++ }
    $1" "$2 in c {next}
    {   b[n++]=$1" "$2; 
        c[$1" "$2]=$3
    }
    END { for (i in b) print a[b[i]], b[i], c[b[i]] }
' file

以上$1" "$2是前兩個字段的串聯,用作數組ac的公共索引,並用作數組b中保留順序的值。

示例使用/輸出

隨着輸入文件file ,你可以簡單地復制和中等鼠標上面的腳本粘貼到包含目錄的xterm file和你的結果是在您指定的順序:

$ awk -v n=1 '{ a[$1" "$2]++ }
>     $1" "$2 in c {next}
>     {   b[n++]=$1" "$2;
>         c[$1" "$2]=$3
>     }
>     END { for (i in b) print a[b[i]], b[i], c[b[i]] }
> ' file
2 a b 125
2 d t 485
1 d f 859
1 a t 154

使用 SUBSEP

正如@JonathanLeffler 在下面的評論中指出的那樣,您還可以提供索引作為a[$1,$2]用於表示多維數組,其中','字符被內置的SUBSEP變量替換為"\\034" 為此還需要調整第二個規則測試和b數組的值。 通過調整,您將擁有:

awk -v n=1 '{ a[$1,$2]++ } 
    $1 SUBSEP $2 in c { next }
    {
        b[n++]=$1 SUBSEP $2
        c[$1,$2]=$3
    }
    END {for (i in b) print a[b[i]], b[i], c[b[i]]}
' file

使用SUBSEP串聯或分離都可以在這里工作,但對於正式的多維陣列模擬,應該使用SUBSEP

如果第 1 列和第 2 列中的鍵是可變長度的,那么我認為awk是首選工具。 這類似於David C. Rankin回答,但它是獨立開發的。

awk '{ if (count[$1, $2]++ == 0) { line[$1, $2] = $0; order[n++] = $1 SUBSEP $2 } }
     END { for (i = 0; i < n; i++) printf "%d %s\n", count[order[i]], line[order[i]] }'

第一行增加第 1 列和第 2 列條目的計數; 如果為 0(在增量之前),則捕獲該行(由第 1 列和第 2 列索引),並按order[n++]捕獲鍵(第 1 列和第 2 列,由SUBSEP )。

最后,按order處理鍵,在countline索引相關數據。

對於您的輸入數據,這會產生:

2 a b 125
2 d t 485
1 d f 859
1 a t 154

但如果鍵是可變長度,它也能正常工作。 有許多可能的改進,例如計算最大計數的長度以便計數右對齊,並且如果您正在處理可變長度的鍵,您可以跟蹤哪個是第 1 列和列中最長的鍵2,所以你也可以對齊鍵。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM