Linux Bash 按唯一列计数和汇总

Linux Bash count and summarize by unique columns

我有一个包含如下行的文本文件(在 Linux Bash 中):

A B C D
A B C J
E B C P
E F G N
E F G P
A B C Q
H F S L
G Y F Q
H F S L

我需要为前 3 列找到具有唯一值的行,打印它们的计数,然后为每个唯一行打印汇总的最后一列,所以结果如下:

3 A B C D,J,Q
1 E B C P
2 E F G N,P
1 G Y F Q
2 H F S L

我试过的:

cat FILE | sort -k1,3 | uniq -f3 -c | sort -k3,5nr

有什么建议吗?

提前致谢!

最简单的方法是执行以下操作:

awk '{key= OFS  OFS ; a[key]=a[key]","; c[key]++}
     END{for(key in a) { print c[key],key,substr(a[key],2) }}' <file>

如果不想重复,可以

awk '{ key= OFS  OFS ; c[key]++ }
     !gsub(",",",",a[key]) {a[key]=a[key]","; }
     END{for(key in a) { print c[key],key,substr(a[key],2) }} <file>

能否请您尝试关注,如果这对您有帮助,请告诉我。 这将为您提供与 Input_file 的 </code>、<code></code> 相同的输出顺序。</p> <pre><code>awk ' !a[,,]++{ b[++count]= FS FS } { c[,,]=c[,,]?c[,,] "," :[=10=] d[ FS FS ]++ } END{ for(i=1;i<=count;i++){ print d[b[i]],c[b[i]] } } ' SUBSEP=" " Input_file

另一个使用 GNU awk 和二维数组删除 </code> 中的重复项:</p> <pre><code>$ awk '{ i= OFS OFS # key to hash a[i][] # store each to separate element c[i]++ # count key references } END { for(i in a) { k=1 # comma counter for output printf "%s %s ",c[i],i # output count and key for(j in a[i]) # each a[]i[j] element printf "%s%s",((k++)==1?"":","),j # output commas and elements print "" # line-ending } }' file

默认随机顺序输出:

2 E F G N,P
3 A B C Q,D,J
1 G Y F Q
1 E B C P
2 H F S L

由于我们使用的是 GNU awk,因此可以通过设置 PROCINFO["sorted_in"]="@ind_str_asc":

轻松影响输出顺序
3 A B C D,J,Q
1 E B C P
2 E F G N,P
1 G Y F Q
2 H F S L

您可以利用 GNU datamash:

$ cat input
A B C D
A B C J
E B C P
E F G N
E F G P
A B C Q
H F S L
G Y F Q
H F S L
$ datamash -t' ' --sort groupby 1,2,3 unique 4 count 4 < input
A B C D,J,Q 3
E B C P 1
E F G N,P 2
G Y F Q 1
H F S L 2

不幸的是,这会将计数输出为最后一列。如果它绝对有必要成为第一列,则必须重新格式化它:

$ datamash -t' ' --sort groupby 1,2,3 unique 4 count 4 < input | awk '{[=11=]=$NF FS [=11=]; NF--}1'
3 A B C D,J,Q
1 E B C P
2 E F G N,P
1 G Y F Q
2 H F S L