CGI/Perl Guide | Learning Center | Forums | Advertise | Login
Site Search: in

  Main Index MAIN
INDEX
Search Posts SEARCH
POSTS
Who's Online WHO'S
ONLINE
Log in LOG
IN

Home: Perl Programming Help: Beginner:
Select lines in a file between pattern

 



tsdjim
New User

Aug 28, 2017, 10:13 AM

Post #1 of 6 (1543 views)
Select lines in a file between pattern Can't Post

I have a file myfile which has text between patterns for each month.

For example:

Auguststart
Some text
some more text
Augustend
Septemberstart
Some text
some more text
Septemberend

For example for August it should select the text between Auguststart and Augustend but the if statement does not select anything in my code below.

$random_file = '/mydir/myfile';
my ( $day, $month, $year ) = ( localtime )[3,4,5];
$month = (
qw/ January February March
April May June
July August September
October November December /
)[$month];

$monthx = $month . 'start';
$monthy = $month . 'end';
open(SESAME, $random_file);
while (<SESAME>) {
if (/^$monthx/../^$monthy/)
{print SESAME};

}
close (SESAME) or die "Could not close sample.txt: $!";


BillKSmith
Veteran

Aug 28, 2017, 11:33 AM

Post #2 of 6 (1539 views)
Re: [tsdjim] Select lines in a file between pattern [In reply to] Can't Post

There is nothing wrong with your logic. If you had used strict and warnings, you would have received an error message referring to the offending statement. (Your print statement is trying to print back to the input file.)

I have replaced your disk file with an in-memory file in order to show the data in the post.

Code
C:\Users\Bill\forums\guru>type tsdjim0.pl 
my $random_file = \<<'END_RANDOM_FILE';
Auguststart
Some text
some more text
Augustend
Septemberstart
Some text
some more text
Septemberend
END_RANDOM_FILE
my ( $day, $month, $year ) = ( localtime )[3,4,5];
$month = (
qw/ January February March
April May June
July August September
October November December /
)[$month];

$monthx = $month . 'start';
$monthy = $month . 'end';
open(SESAME, '<', $random_file);
while (<SESAME>) {
if (/^$monthx/../^$monthy/)
{print };

}
close (SESAME) or die "Could not close sample.txt: $!";


C:\Users\Bill\forums\guru>perl tsdjim0.pl
Auguststart
Some text
some more text
Augustend


I recommend several changes to improve the style.
  • Always use strict and warnings

  • Always use three-argument form of open

  • Always check open for failure.

  • Always use lexical (my) file-handles

  • Format your code with perltidy


  • Here is an improved version of your code:

    Code
    use strict; 
    use warnings;

    my $random_file = \<<'END_RANDOM_FILE';
    Auguststart
    Some text
    some more text
    Augustend
    Septemberstart
    Some text
    some more text
    Septemberend
    END_RANDOM_FILE

    my $month = (qw/
    January February March
    April May June
    July August September
    October November December /
    )[(localtime)[4]];

    my $monthx = $month . 'start';
    my $monthy = $month . 'end';
    open( my $SESAME, '<', $random_file ) or die "Cannot open input file\n:$!";
    while (<$SESAME>) {
    print if /^$monthx/ .. /^$monthy/ ;
    }
    close($SESAME) or die "Could not close sample.txt: $!";

    Good Luck,
    Bill


    tsdjim
    New User

    Aug 28, 2017, 12:18 PM

    Post #3 of 6 (1536 views)
    Re: [tsdjim] Select lines in a file between pattern [In reply to] Can't Post

    Thanks Bill, that works great.

    How can I exclude the pattern line from the print result.

    Ron


    Chris Charley
    User

    Aug 28, 2017, 1:22 PM

    Post #4 of 6 (1533 views)
    Re: [tsdjim] Select lines in a file between pattern [In reply to] Can't Post

    To exclude the pattern line, say print unless . . .


    Code
    #!/usr/bin/perl 
    use strict;
    use warnings;
    use Time::Piece;

    open my $fh, '<', \<<EOF;
    Auguststart
    Some text
    some more text
    Augustend
    Septemberstart
    Some text
    some more text
    Septemberend
    EOF

    my $month = localtime->strftime("%B");

    while (<$fh>) {
    if (/^${month}start$/../^${month}end$/) {
    print unless /^$month(?:start|end)$/;
    }
    }


    (Note that I used Time::Piece to get the name of the month. It will eliminate the need to enumerate the month names as your and Bill's code does).


    (This post was edited by Chris Charley on Sep 3, 2017, 1:40 PM)


    BillKSmith
    Veteran

    Aug 28, 2017, 2:57 PM

    Post #5 of 6 (1529 views)
    Re: [Chris Charley] Select lines in a file between pattern [In reply to] Can't Post

    Thanks for the note about strftime in Time::Piece. I have always used the copy in POSIX (When I think of it at all).
    Good Luck,
    Bill


    tsdjim
    New User

    Aug 30, 2017, 10:54 AM

    Post #6 of 6 (1505 views)
    Re: [BillKSmith] Select lines in a file between pattern [In reply to] Can't Post

    Thanks Bill and Chris for your solution.

     
     


    Search for (options) Powered by Gossamer Forum v.1.2.0

    Web Applications & Managed Hosting Powered by Gossamer Threads
    Visit our Mailing List Archives