Awk:计算每列的每个字符的出现次数,并按定义顺序写入

时间:2014-11-01 17:06:11

标签: linux unix awk

我需要计算每列中每个字符的出现次数。 我的输入如下:

0 H B
0 G G
0 B b
0 T G
0 0 T

输出应该如下:

1 H=0 G=0 I=0 B=0 b=0 T=0 0=5
2 H=1 G=1 I=0 B=1 b=0 T=1 0=1
3 H=0 G=1 I=0 B=1 b=1 T=2 0=0

我尝试修改Unix&Linux forum

中的脚本
awk -F " " '
BEGIN{
cond=1
}
{      
if(cond == 1) {
    for(i = 1; i <= NF; i++) {
        a[i " " "H"]=0
        a[i " " "G"]=0
        a[i " " "I"]=0
        a[i " " "B"]=0
        a[i " " "b"]=0
        a[i " " "T"]=0
        a[i " " "0"]=0
    }
    cond=0
}
for(i = 1; i <= NF; i++) {
    a[i " " $i]++
}
}
END {  
for(x in a) print x " " a[x]
}'  INPUT_FILE  |

awk '
{
a[$1] = (a[$1] == "" ? $1 : a[$1]) " " $2 "=" $3
    if(max < $1) max = $1
}
END {  
for(i = 1; i <= max; i++) print a[i]
}'

但in输出文件主要以0而不是H开始。

任何帮助将不胜感激!我不熟悉awk ......

1 个答案:

答案 0 :(得分:0)

这个awk脚本产生你想要的输出:

$ awk 'BEGIN{c["H"];c["G"];c["I"];c["B"];c["b"];c["T"];c["0"]}
       {for(i=1;i<=NF;++i)++a[i,$i]}
       END{for(i=1;i<=NF;++i){
           printf "%s ",i;
           for(j in c)printf "%s=%d ",j,a[i,j];print ""}}' file.txt
1 B=0 G=0 T=0 H=0 b=0 I=0 0=5
2 B=1 G=1 T=1 H=1 b=0 I=0 0=1
3 B=1 G=2 T=1 H=0 b=1 I=0 0=0

初始化BEGIN块中的数组c,使其包含每个字符的键。循环遍历每一行中的每个字段。增加数组a的值,该数组的键包含字段编号和字段中的字符。处理完每条记录后,循环遍历数组c的字段和键,打印数组a中的计数。

数组中的键没有排序,因此当您使用for x in y循环时,不能依赖于输出的特定顺序。如果您想按特定顺序打印密钥,则必须自己指定。例如,你可以这样做:

$ awk '{for(i=1;i<=NF;++i)++a[i,$i]}
       END{for(i=1;i<=NF;++i){
           printf "%s ",i
           printf "H=%d ",  a[i,"H"]
           printf "G=%d ",  a[i,"G"]
           printf "I=%d ",  a[i,"I"]
           printf "B=%d ",  a[i,"B"]
           printf "b=%d ",  a[i,"b"]
           printf "T=%d ",  a[i,"T"]
           printf "0=%d\n", a[i,"0"]
       }}' file.txt