[英]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
是前兩個字段的串聯,用作數組a
和c
的公共索引,並用作數組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
處理鍵,在count
和line
索引相關數據。
對於您的輸入數據,這會產生:
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.