How can I print a matching line, one line immediately above it and one line immediately below?

后端 未结 8 1051
你的背包
你的背包 2020-12-16 07:23

From a related question asked by Bi, I\'ve learnt how to print a matching line together with the line immediately below it. The code looks really simple:

#!p         


        
相关标签:
8条回答
  • If you don't mind losing the ability to iterate over a filehandle, you could just slurp the file and iterate over the array:

    #!/usr/bin/perl
    
    use strict; # always do these
    use warnings;
    
    my $range = 1; # change this to print the first and last X lines
    
    open my $fh, '<', 'FILE' or die "Error: $!";
    my @file = <$fh>;
    close $fh;
    
    for (0 .. $#file) {
      if($file[$_] =~ /Pattern/) {
        my @lines = grep { $_ > 0 && $_ < $#file } $_ - $range .. $_ + $range;
        print @file[@lines];
      }
    }
    

    This might get horribly slow for large files, but is pretty easy to understand (in my opinion). Only when you know how it works can you set about trying to optimize it. If you have any questions about any of the functions or operations I used, just ask.

    0 讨论(0)
  • 2020-12-16 08:22

    Command line grep is the quickest way to accomplish this, but if your goal is to learn some Perl then you'll need to produce some code.

    Rather than providing code, as others have already done, I'll talk a bit about how to write your own. I hope this helps with the brain-lock.

    • Read my previous answer on how to write a program, it gives some tips about how to start working on your problem.
    • Go through each of the sample programs you have, as well as those offered here and comment out exactly what they do. Refer to the perldoc for each function and operator you don't understand. Your first example code has an error, if 2 lines in a row match, the line after the second match won't print. By error, I mean that either the code or the spec is wrong, the desired behavior in this case needs to be determined.
    • Write out what you want your program to do.
    • Start filling in the blanks with code.

    Here's a sketch of a phase one write-up:

    # This program reads a file and looks for lines that match a pattern.
    
    # Open the file
    
    # Iterate over the file
    # For each line
    #    Check for a match
    #    If match print line before, line and next line.
    

    But how do you get the next line and the previous line?

    Here's where creative thinking comes in, there are many ways, all you need is one that works.

    • You could read in lines one at a time, but read ahead by one line.
    • You could read the whole file into memory and select previous and follow-on lines by indexing an array.
    • You could read the file and store the offset and length each line--keeping track of which ones match as you go. Then use your offset data to extract the required lines.
    • You could read in lines one at a time. Cache your previous line as you go. Use readline to read the next line for printing, but use seek and tell to rewind the handle so that the 'next' line can be checked for a match.

    Any of these methods, and many more could be fleshed out into a functioning program. Depending on your goals, and constraints any one may be the best choice for that problem domain. Knowing how to select which one to use will come with experience. If you have time, try two or three different ways and see how they work out.

    Good luck.

    0 讨论(0)
提交回复
热议问题