in reply to Counting lines matching a certain pattern following a select word

Hi moon36 and welcome to PerlMonks!

I have absolutely no idea how to begin coding this (I am super new to perl).

There are several ways this can be done, but always begin your scripts with:

use strict; use warnings;

These pragmas will alert you to problems in your scripts which you may otherwise spend hours trying to figure out. Use them unfailingly.

Consider each "Frame: " as a record. If you do, you can set Perl's record separator ($/) to that, so your file is read a 'chunk' at a time which, in this case, will be a frame at a time. Then you can process the lines within that 'chunk' to see how many contain "C" in them. Here's the first line after the pragmas:

local $/ = 'Frame: ';

Next, you can use a typical structure for reading a file that's passed to the Perl script on the command line--and this leaves opening and closing the file to Perl:

while (<>) { }

Well, as it stands, the while loop will certainly read through a file's lines--assigning each line to Perl's default scalar ($_)--but that's all, since nothing's done with the file's lines. Perhaps the first thing to do is to grab the frame number, for later display:

next unless my ($frame) = /(\d+)/;

A regular expression is used here (and it implicitly operates on $_) to capture the decimals just after the "Frame: " part, and the capture is assigned to $frame. The next unless is used to get the next record unless the assignment is successful.

Next part: count the "C"s in the chunk. Here, too, there are different ways to do this, so here's one way:

my $count = grep /C/, split /\n/;

First the chunk is split on the newlines, which creates a list of the lines in the chunk. Next, grep is used on each line. If "C" is found in the line (the regex /C/ is used for this--again implicitly operating on $_), the line will pass through grep. Since $count is a scalar, the results of grep are evaluated in scalar context, so the number of lines is assigned to $count. (Had there been an array, such as @array instead of $count, all the lines which contained "C" would be passed to it.)

Last, the results of analyzing the chunk needs to be printed:

print "Frame: $frame " . $count . "\n";

Putting this all together, you get the following:

use strict; use warnings; local $/ = 'Frame: '; while (<>) { next unless my ($frame) = /(\d+)/; my $count = grep /C/, split /\n/; print "Frame: $frame " . $count . "\n"; }

Usage: perl script.pl inFile [>outFile]

The last, optional parameter directs output to a file.

Output on your dataset:

Frame: 11 7 Frame: 12 7

Hope this helps!