Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Count pattern occurrence in each line of file?

My file looks like this:

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

grep -c 'chfl' filename, gives me the number of occurrence of chfl, but I want to count occurrence of chfl per line. Like this:

id12 2
id14 1
id13 0
id23 1

Also how do I do the same with two patterns to match? Like chfl and dll?

like image 772
user_newbie Avatar asked Jan 22 '26 12:01

user_newbie


2 Answers

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

Or simply:

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

Tested below:

> 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
> 

Also in awk:(Logic here remains the same as above one in perl)

awk '{a=0;
     for(i=1;i<=NF;i++)if($i~/chfl/)a++;
     print $1,a}' your_file
like image 112
Vijay Avatar answered Jan 25 '26 07:01

Vijay


A Perl version that copes with multiple strings.

#!/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;

A couple of test runs:

$ ./cgrep chfl dll cgrep.txt 
chfl: 4
$ ./cgrep chfl dll cgrep.txt 
chfl: 4
dll: 2
like image 44
Dave Cross Avatar answered Jan 25 '26 06:01

Dave Cross



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!