计算每行中匹配字段的数量

时间:2015-06-29 00:21:55

标签: regex perl awk

我有一个文件,其中每一行都有一定数量的字段匹配" ./."看起来像是:

chrM    57  .   T   C   4848.99 GT:AD:DP:GQ:PL  ./. 1/1:1,149:150:99:4903,439,0 0/0:202,0:202:99:0,541,6030 0/0:249,1:250:99:0,646,7558 0/0:249,1:250:99:0,647,7484 0/0:111,0:111:99:0,304,3346 0/0:171,0:172:99:0,397,4599 0/0:118,0:118:99:0,340,3827 0/0:247,0:247:99:0,650,7312 0/0:218,0:219:99:0,611,6728 0/0:242,0:242:99:0,686,7589 0/0:250,0:250:99:0,689,7599 0/0:144,0:144:99:0,409,4608 0/0:250,0:250:99:0,680,7585 0/0:141,3:144:99:0,321,4233 0/0:71,0:71:99:0,205,2260   0/0:204,0:205:99:0,568,6312 ./. 0/0:191,0:191:99:0,523,5874 0/0:249,0:250:99:0,665,7443 0/0:142,0:143:99:0,340,3991 0/0:218,0:218:99:0,575,6612 0/0:247,0:247:99:0,665,7412 0/0:250,0:250:99:0,692,7768 0/0:250,0:250:99:0,689,7749 0/0:247,2:249:99:0,674,7574

我想计算完全匹配的字段数" ./."在每一行中,打印每行的匹配数。我相信我可以做类似下面的代码,但代码不起作用(我是perl的新手)。我认为在awk中应该有一个更简单的解决方案。

#! perl -w  

my$F=shift@ARGV;
open IN, "$F";
while(<IN>){
    $num1++ while ($string1 =~ m/\.\/\./g);
    print "The first line has $num1\n";
    next;
}

4 个答案:

答案 0 :(得分:4)

你可以这样做:

LinkedList.java:778

Ideone Demo

答案 1 :(得分:2)

这是另一种选择:

use strict;
use warnings;

while (<>) {
    print "Line $. has ", ( split m|\./\.| ) - 1, "\n";
}

用法:perl script.pl dataFile [>outFile]

括号表示可用于将输出发送到文件的可选参数。

脚本split是您要匹配的字段模式上的每一行,然后返回split中元素-1的数量,作为匹配“./”的字段数。 。在您的样本行上,它返回:

Line 1 has 2

希望这有帮助!

答案 2 :(得分:1)

在awk中:

$ awk '{c=0; for (i=1;i<=NF;i++) c+=($i=="./."); printf "Line %s has %s\n",NR,c+0;}' file
Line 1 has 2

如何运作

默认情况下,awk会将每条记录(行)拆分为字段。我们遍历所有寻找与./.平等的字段。

  • c=0

    将计数设置为零。

  • for (i=1;i<=NF;i++) c+=($i=="./.")

    每次字段与c完全匹配时,

    增加计数./.

    $i是第i个字段的内容。如果字段与$i=="./."完全匹配,则./.为1。因此,c+=($i=="./.")为每个匹配字段增加c个。

  • printf "Line %s has %s\n",NR,c+0

    打印此行的结果。

答案 3 :(得分:1)

您需要设置迭代器来捕获每一行。 Perl中的匹配计数语法也有点奇怪

my$F=shift@ARGV;
open IN, "$F";
$s = "\.\/\.";
while($string1 = <IN>){
    $num1 = () = $string1 =~ m/$s/gi;
    print "foo: $num1 $string1\n";
    next;