mitso874 has asked for the wisdom of the Perl Monks concerning the following question:

Hi, I use a perl script to find times from several files. The files used to have all the same header so I was keying it off a specific line (line 13), but now the headers change and need to revise the perl script to key off of a word ("MILLISEC"). Not sure how to do this. Here's my code:
my $findline = 13; for ($i=$Drop; $i<=$Last; $i++){ print TIMEFILE1 "Drop $i\n"; for ($k=1; $k<=$KTM;$k++){ $String1= "RK" . "$i" . "$suf[$k-1]"; $file = $String1; if (-e $file){ open (F, $file) || ("Could not open $file!"); $lines++ while (<F>); close (F); open (F, $file) || ("Could not open $file!"); while ($line = <F>) { if ($. == $findline){ ($field1, $field2, $field3, $field4) = split ',', $ +line; print TIMEFILE1 "$field2 : $field3 : $field4 \t"; } if ($. == $lines){ ($field1, $field2, $field3, $field4) = split ',', $ +line; print TIMEFILE1 "$field2 : $field3 : $field4 \t $St +ring1\n"; } } $lines = 0; close (F); } } }

Replies are listed 'Best First'.
Re: Finding a line after a keyword
by roboticus (Chancellor) on May 12, 2015 at 22:22 UTC

    mitso874:

    Generally, you would simply read lines until you find the 'trigger' (MILLISEC, in your case), then count off the lines until you get the data you want. If the MILLISEC line was three lines before the end of the header, for example, you'd do something like:

    # Wait for 'MILLISEC' to appear while (<F>) { last if /MILLISEC/; } # your current code.... my $findline=3; # with this adjusted to the right value...

    Note: It would be nice if you'd update your post and add code tags around your code to make it easier to read. <c>Your code goes between these</c>.

    ...roboticus

    When your only tool is a hammer, all problems look like your thumb.

Re: Finding a line after a keyword
by ww (Archbishop) on May 12, 2015 at 23:39 UTC

    My brain needed something brainless to do. So I checked to see if I could translate the unformatted mess in the OP into something I could read and chew on. (Don't count on this ever happening again; see, instead Markup in the Monastery.

    The exercise was not terribly productive, as the raw translation (minus my errors in fixup) yielded so many errors that perl -c D:\PMonks\1126473.pl balked at further checking. But the good news was that most of what the check turned up with accounted for by my use of strict and thus were fairly easy to identify. However, what appears as Ln3 below was missing an Open_Paren:

    while ($line = <F>) { if ($. == $findline) { ($field1, $field2, $field3, $field4) = split ' +,', $line;

    That, alone, is a no-no here. When you post code, cut'n'paste from something that compiles; don't retype (and if that's what you did here, that may be the cause of the missing paren) because retyping invites typos.

    That said, there's another deficiency in your code: you tell us that you're now keying off the word "MILLISEC" but you don't specify whether that's -- well, somewhere in the variable headers -- or somewhere in the data AND a reliable number of lines before the data you're trying to extract.

    If that latter, of course, roboticus' response, above, is pretty much all you need (assuming you have actual working code. If the former, what's the relationship between the appearance of "MILLISEC" and the location of the data you want? Obviously, we need to know that to help, and the lack of that information points to another possible weakness in your question -- the lack of sample data.

    So, this is only a WAG: if "MILLISEC" has a consistent relationship (in lines of separation) to your data, you need only do exactly as advised above; if the relationship is NOT one of lines of separation then your first step has to be finding a quantifiable relationship or finding a different key that is a reliable indicator.


    ++$anecdote ne $data

    check Ln42!