我试图获取每列中每个 uniq 字符串的总计数(总和),并按相应的列顺序输出。
我需要在一个强大的 awk 命令中使用它,因为不同的完整输入通常是数千行和列。
我自己尝试过这样做,但没有任何运气。我想我已经很接近了,这就是我使用代码的地方,尽管它显然不起作用:
awk -F ',' '{ for(N=1; N<=NF; N++) {{count[$N]++} END {for (word in count) print word, count[word]}}}'
我对上述代码的想法是,如果我运行的话,我可以获得单个指定列的所需输出,现在让我们说第 2 列:
awk '{count[$2]++} END {for (word in count) print word, count[word]}'
但是我需要为每一列提供这种类型的输出。所以我试图循环遍历列来实现这一点,但它失败了:(
以下是一些示例数据:
输入示例:
M,M,M,M
N,N,N,N
A,M,G,L
P,P,P,P
A,N,G,L
P,N,P,L
A,A,A,A
C,C,C,C
A,M,G,C
L,L,L,L
G,G,G,G
相应的期望输出:
M 1,M 2,M 1,M 1
N 1,N 2,N 1,N 1
A 3,A 1,A 1,A 1
P 1,P 1,P 1,P 1
L 1,L 1,L 1,L 3
G 1,G 1,G 3,G 1
C 1,C 1,C 1,C 1
为了解释输出,示例输入中的第一列有 3 个 A,所有其他字母各只有 1 个,因此该列的输出为:
M 1
N 1
A 3
P 1
L 1
G 1
C 1
我编写了这段代码并且它可以工作,但理想情况下我想在 awk 命令中实现它:
for i in $(seq $NumberOfColumns);do
ColumnOutput=$(awk -F ',' -v x=$i '{count[$x]++} END {for (word in count) print word, count[word]}' file)
TotalOutput=$(paste <(echo "$TotalOutput") <(echo "$ColumnOutput") -d ,)
done
echo "$TotalOutput" | sed 's/^,//g'
答案1
我认为这会有所帮助:
$ awk -F"," '
NR==FNR { for (i=1;i<=NF;i++) {a[i,$i]+=1;b[$i]=$i} next }
{ for (i=1;i<=NF;i++)if(b[$1]) printf "%s %s,",$1,a[i,$1];else next; print ""; delete b[$1] }
' file file
M 1,M 3,M 1,M 1,
N 1,N 3,N 1,N 1,
A 4,A 1,A 1,A 1,
P 2,P 1,P 2,P 1,
C 1,C 1,C 1,C 2,
L 1,L 1,L 1,L 3,
G 1,G 1,G 4,G 1,
答案2
使用乐(以前称为 Perl_6)
~$ raku -e 'my @a = [Z] lines.map: *.split(","); my @b; \
for ^@a -> $row { \
for ^$row.elems -> $col { my %h; \
%h{$_}++ for @a[$row]>>.[$col]; \
@b.push: %h.sort }}; \
for ^@b>>.elems.max -> $j { \
put @b.map({ $_.[$j] // (" " => "0") }).join: "," };' file
或者(更简单):
~$ raku -e 'my @a = [Z] lines.map: *.split(","); my @b; \
for ^@a -> $row { \
my %h is BagHash = @a[$row]; \
@b.push: %h.sort }; \
for ^@b>>.elems.max -> $j { \
put @b.map({ $_.[$j] // (" " => "0") }).join: "," };' file
以下是用 Raku(Perl 编程语言家族的成员)编写的答案。 Raku 具有对 Unicode 的内置高级支持。上面的代码利用了 Perl 系列功能,例如@
-sigiled 数组和%
-sigiled 哈希(即字典/键值对)。
首先,使用 逐行读取数据
lines
,每个数据都split
以逗号分隔。为了交换行和列,[Z]
使用运算符,并将数据存储在@a
数组中。接下来,
@a
数组将被迭代,首先是 by,$row
然后是 by$col
,以便对于每个$row
单元格“key”($_
) 都存储在%h
散列(第一个答案)或 BagHash(第二个答案)中。分析每一行后,键/值数据将存储在@b
数组中。最后确定
max
键/值的数量(通过),并输出数据,注意在特定列的键可能未定义的地方插入零(OP 可以在此处使用,而不是):elems
put
0
"Nil"
" "
示例输入(注意列中键的数量不相等):
M,M,M,M
N,N,N,N
A,M,G,L
P,P,P,P
A,N,G,L
P,N,P,L
A,A,A,A
C,C,C,C
A,M,G,X
L,L,L,L
G,G,G,G
示例输出(键/值对\t
以制表符分隔):
A 4,A 1,A 1,A 1
C 1,C 1,C 1,C 1
G 1,G 1,G 4,G 1
L 1,L 1,L 1,L 4
M 1,M 3,M 1,M 1
N 1,N 3,N 1,N 1
P 2,P 1,P 2,P 1
0, 0, 0,X 1
https://docs.raku.org/type/BagHash
https://docs.raku.org
https://raku.org