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
我有一个包含如下行的文本文件(在 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