计算字符的出现

时间:2019-07-11 16:23:56

标签: bash awk

我有一个看起来像这样的文件

chr1A_p1
chr1A_p2
chr10B_p1
chr10A_p1
chr11D_p2
chr18B_p2
chr9D_p1

我需要计算A,B和D发生的时间。我个人会这样做

awk '{if($1~/A/) print $0 }' < test.txt | wc
awk '{if($1~/B/) print $0 }' < test.txt | wc
awk '{if($1~/D/) print $0 }' < test.txt | wc

如何连接这些行,以便我可以仅通过一个衬线而不是3条单独的行来计算A,B,D的数量。

4 个答案:

答案 0 :(得分:2)

对于特定的行格式(其中所需的字符在_之前):

$ awk -F"_" '{ seen[substr($1, length($1))]++ }END{ for(k in seen) print k, seen[k] }' file
A 3
B 2
D 2

答案 1 :(得分:2)

计数发生通常是通过跟踪计数器来完成的。因此,OP的awk行中只有一条;

awk '{if($1~/A/) print $0}' < test.txt | wc

可以改写为

awk '($1~/A/){c++}END{print c}' test.txt

对于多种情况,您现在可以执行以下操作:

awk '($1~/A/){c["A"]++}
     ($1~/B/){c["B"]++}
     ($1~/D/){c["D"]++}
     END{for(i in c) print i,c[i]}' test.txt

现在您甚至可以多清理一点:

awk '{c["A"]+=($1~/A/)}
     {c["B"]+=($1~/B/)}
     {c["D"]+=($1~/D/)}
     END{for(i in c) print i,c[i]}' test.txt

您可以将其进一步清理为:

awk 'BEGIN{split("A B D",a)}
     {for(i in a) c[a[i]]+=($1~a[i])}
     END{for(i in c) print i,c[i]}' test.txt

但是这些情况只是计算包含字母的一行出现的次数,而不是该字母出现的次数。

awk 'BEGIN{split("A B D",a)}
     {for(i in a) c[a[i]]+=gsub(a[i],"",$1)}
     END{for(i in c) print i,c[i]}' test.txt

答案 2 :(得分:1)

抢救Perl!

perl -lne '$seen{$1}++ if /([ABD])/; END { print "$_:$seen{$_}" for keys %seen }' < test.txt
  • -n逐行读取输入
  • -l从输入中删除换行符并将其添加到输出中
  • 哈希表%seen用于保留每个符号的出现次数。每次匹配它都会被捕获,并且哈希中的相应字段会增加。
  • END在文件结束时运行。它输出哈希的所有键,即匹配的字符,每个键后跟出现的次数。

答案 3 :(得分:1)

数据文件:

+---------+
| Language|
+---------+
|Spanish  | 
|spanish  | 
|venezla  | 
|venezuala| 
|irish    | 
|Irish    |
+---------+

script.awk

chr1A_p1
chr1A_p2
chr10B_p1
chr10A_p1
chr11D_p2
chr18B_p2
chr9D_p1

执行:

BEGIN {
    arr["A"]=0
    arr["B"]=0
    arr["D"]=0
} 
/A/ { arr["A"]++ }
/B/ { arr["B"]++ } 
/D/ { arr["D"]++ }  
END {
    printf "A: %s, B: %s, D: %s", arr["A"], arr["B"], arr["D"]
}

结果:

 awk -f script.awk datafile