计算每行文件中的模式?

时间:2014-03-17 12:36:08

标签: regex perl sed awk grep

我的文件如下:

id12 ack dko hhhh chfl dkl dll chfl
id14 slo ksol chfl dloo
id13 mse
id23 clos chfl dll alo

grep -c 'chfl' filename,给出了chfl的出现次数,但我想计算每行chfl的出现次数。像这样:

id12 2
id14 1
id13 0
id23 1

另外,如何匹配两种模式?与chfldll一样?

8 个答案:

答案 0 :(得分:2)

perl -lane 'undef $c;
            for(@F){$c++ if(/^chfl$/)};
            print "$F[0] ",$c?$c:"0"' your_file

或者简单地说:

perl -lane '$c=0;
            for(@F){$c++ if(/^chfl$/)};
            print "$F[0] $c"' your_file

测试如下:

> cat temp
id12 ack dko hhhh chfl dkl dll chfl
id14 slo ksol chfl dloo
id13 mse
id23 clos chfl dll alo
> perl -lane '$c=0;for(@F){$c++ if(/^chfl$/)};print "$F[0] $c"' temp
id12 2
id14 1
id13 0
id23 1
> 

同样在awk中:(这里的逻辑与perl中的逻辑相同)

awk '{a=0;
     for(i=1;i<=NF;i++)if($i~/chfl/)a++;
     print $1,a}' your_file

答案 1 :(得分:2)

处理多个字符串的Perl版本。

#!/usr/bin/perl

use strict;
use warnings;
use 5.010;

die "Usage: $0 pattern [pattern ...] file\n" unless @ARGV > 1;

my @patterns;
until (@ARGV == 1) {
  push @patterns, shift;
}

my $re = '(' . join('|', map { "\Q$_\E" } @patterns) . ')';

my %match;
while (<>) {
  if (my @matches = /$re/g) {
    $match{$_}++ for @matches;
  }
}

say "$_: $match{$_}" for sort keys %match;

几次试运行:

$ ./cgrep chfl dll cgrep.txt 
chfl: 4
$ ./cgrep chfl dll cgrep.txt 
chfl: 4
dll: 2

答案 2 :(得分:1)

怎么样:

my %res;
while(<DATA>) {
    chomp;
    my ($id,$rest) = $_ =~ /^(\S+)(.*)$/;
    $res{chfl}{$id} =()= $rest =~ /(chfl)/g;
    $res{dll}{$id} =()= $rest =~ /(dll)/g;
}
say Dumper\%res;

__DATA__
id12 ack dko hhhh chfl dkl dll chfl
id14 slo ksol chfl dloo
id13 mse
id23 clos chfl dll alo

<强>输出:

$VAR1 = {
          'dll' => {
                     'id13' => 0,
                     'id12' => 1,
                     'id23' => 1,
                     'id14' => 0
                   },
          'chfl' => {
                      'id13' => 0,
                      'id12' => 2,
                      'id23' => 1,
                      'id14' => 1
                    }
        };

答案 3 :(得分:1)

使用此:

awk 'BEGIN {print "id\tchfl\tdll\n--------------------"}{c=d=i=0;while(i++<NF){if($i=="chfl")c++; if($i=="dll")d++}; print $1,c,d}' OFS="\t" file
id      chfl    dll
--------------------
id12    2       1
id14    1       0
id13    0       0
id23    1       1

答案 4 :(得分:1)

用grep打一个班轮:

while read line ; do echo $line | grep -o 'chfl' | wc -l  ; done < your_file

-o在新行上输出每次出现,并且wc对它们进行计数。

编辑多种模式:

patterns=(chfl dll)

while read line ; do
    for pattern in ${patterns[@]} ; do
        echo -ne $pattern"\t" ; echo $line | grep -o $pattern | wc -l 
    done
done < your_file

答案 5 :(得分:1)

awk的另一个版本:

$ awk '{c1=gsub(var1,x);c2=gsub(var2,x);print $1,var1"="c1,var2"="c2}' var1="chfl" var2="dll"  file
id12 chfl=2 dll=1
id14 chfl=1 dll=0
id13 chfl=0 dll=0
id23 chfl=1 dll=1

只需在文件末尾传递要计数的变量即可。

答案 6 :(得分:0)

您可以使用此awk

awk '{d=c=0;for(i=1;i<=NF;i++){ if($i ~ /chfl/)c++; if($i ~ /dll/)d++;} print $1,c,d}' yourfile

答案 7 :(得分:0)

perl -ne 'my $c=s/chfl//g||0;my $d=s/dll//g||0;s/ .*//s;print "$_ chfl $c dll $d\n"' file

说明:

    标量上下文中的
  • s///g返回替换次数
  • ||0如果没有匹配项,请确保该变量设置为零
  • s/ .*//s抛弃$_的第一个空格中的所有内容,仅留下ID

它将产生以下输出:

id12 chfl 2 dll 1
id14 chfl 1 dll 0
id13 chfl 0 dll 0    
id23 chfl 1 dll 1