Printing the next line of text of the file

Discussion in 'Perl Misc' started by Nene, Apr 19, 2007.

  1. Nene

    Nene Guest

    I wrote a perl script that opens a file. I wrote a regex that
    captures $1 $2 and prints it to output. What I want it to do which I
    can't figure out is to print the next line (which has a regex that I
    need to capture as well) under the line that has the the regex but I
    can't figure it out so far. Any help will be greatly appreciated.

    #!/usr/bin/perl -w
    use strict;
    use diagnostics;


    open( FILE, $ARGV[0] ) || die "can't open file!";
    my @TEST = <FILE>;

    foreach my $current_line (@TEST) {

    if ($current_line =~ /^\S+ (\d{4}-\d{2}-\d{2}) (\d{2}:\d{2}:\d{2}) \S+
    \S+/) {
    print "$1 $2\n";
    ## But I also want to print a regex from the line underneath the
    $current_line ###
    }
    }
     
    Nene, Apr 19, 2007
    #1
    1. Advertising

  2. Nene

    Mirco Wahab Guest

    Nene wrote:
    > I wrote a perl script that opens a file. I wrote a regex that
    > captures $1 $2 and prints it to output. What I want it to do which I
    > can't figure out is to print the next line (which has a regex that I
    > need to capture as well) under the line that has the the regex but I
    > can't figure it out so far. Any help will be greatly appreciated.
    >
    > #!/usr/bin/perl -w
    > use strict;
    > use diagnostics;
    > open( FILE, $ARGV[0] ) || die "can't open file!";
    > my @TEST = <FILE>;
    > foreach my $current_line (@TEST) {
    > if ($current_line =~ /^\S+ (\d{4}-\d{2}-\d{2}) (\d{2}:\d{2}:\d{2}) \S+
    > \S+/) {
    > print "$1 $2\n";
    > ## But I also want to print a regex from the line underneath the
    > $current_line ###


    I don't really know what you mean with all these 'regex in the line's,
    but if you want to match regex_2 only after regex_1 matched a line
    before, then the following *could* work (depending on your data,
    which nobody knows).

    use strict;
    use warnings;

    open( my $fh, '<', shift ) or die "can't open file $!";

    my $cnt = 1;
    my $rg_1 = qr/^\S+ (\d{4}-\d{2}-\d{2}) (\d{2}:\d{2}:\d{2}) \S+ \S+(?{$cnt=0})/;
    my $rg_2 = qr/(.)(.+)(?{$cnt=1})/;

    for( <$fh> ) {
    print "$1 $2\n" if /$rg_1/ || (!$cnt++ && /$rg_2/)
    }
    ...

    Maybe there are better solutions, but an
    understanding of your concrete problem
    would be the prerequisite ...

    Regards

    Mirco
     
    Mirco Wahab, Apr 19, 2007
    #2
    1. Advertising

  3. Nene

    Nene Guest

    On Apr 19, 6:58 pm, Mirco Wahab <> wrote:
    > Nene wrote:
    > > I wrote a perl script that opens a file. I wrote a regex that
    > > captures $1 $2 and prints it to output. What I want it to do which I
    > > can't figure out is to print the next line (which has a regex that I
    > > need to capture as well) under the line that has the the regex but I
    > > can't figure it out so far. Any help will be greatly appreciated.

    >
    > > #!/usr/bin/perl -w
    > > use strict;
    > > use diagnostics;
    > > open( FILE, $ARGV[0] ) || die "can't open file!";
    > > my @TEST = <FILE>;
    > > foreach my $current_line (@TEST) {
    > > if ($current_line =~ /^\S+ (\d{4}-\d{2}-\d{2}) (\d{2}:\d{2}:\d{2}) \S+
    > > \S+/) {
    > > print "$1 $2\n";
    > > ## But I also want to print a regex from the line underneath the
    > > $current_line ###

    >
    > I don't really know what you mean with all these 'regex in the line's,
    > but if you want to match regex_2 only after regex_1 matched a line
    > before, then the following *could* work (depending on your data,
    > which nobody knows).
    >
    > use strict;
    > use warnings;
    >
    > open( my $fh, '<', shift ) or die "can't open file $!";
    >
    > my $cnt = 1;
    > my $rg_1 = qr/^\S+ (\d{4}-\d{2}-\d{2}) (\d{2}:\d{2}:\d{2}) \S+ \S+(?{$cnt=0})/;
    > my $rg_2 = qr/(.)(.+)(?{$cnt=1})/;
    >
    > for( <$fh> ) {
    > print "$1 $2\n" if /$rg_1/ || (!$cnt++ && /$rg_2/)
    > }
    > ...
    >
    > Maybe there are better solutions, but an
    > understanding of your concrete problem
    > would be the prerequisite ...
    >
    > Regards
    >
    > Mirco


    Thank you for responding and I apologize for not being clear.

    I want to print (2007-04-18) and (00:05:05) and I want to print where
    (login_id = 'XSKW0010') which is the next line following this huge
    select query.

    Here is the data: (remember, everything from 00004C09 to 'restrict
    ip' ) is one line.

    00004C09 2007-04-18 00:05:05 12241 554188953 " select user.status,
    user.user_id, user.company_id, isnull(t.detail1),'-1',t.detail1) as
    ExpirationDate , if(isnull(t2.detail1),'0',t2.detail1) as inhouse,
    c.company_status,c.company_name , a.line1 as address1 , a.city as
    city ,a.state as state ,a.zip as zip, t3.detail1 as iprestricted from
    hello.user as user , crapwise.company c LEFT JOIN crapwise.address a
    ON c.main_address_id = a.address_id LEFT JOIN crapwise.tag_table t ON
    t.user_id = user.user_id and t.company_id = user.company_id and
    t.category = 'UserFlag' and t.sub_category = 'ExpirationDate' LEFT
    JOIN crapwise.tag_table t2 ON t2.user_id = user.user_id and
    t2.company_id = user.company_id and t2.category = 'User Options' and
    t2.sub_category = 'InhouseSOAPUser' LEFT JOIN crapwise.tag_table t3
    ON t3.company_id = user.company_id and t3.category =
    'company security' and t3.sub_category = 'restrict ip'
    where login_id = 'WSKW0010' and password = 'xxxxxxxxx' and
    c.company_id =
     
    Nene, Apr 20, 2007
    #3
  4. Nene

    Mirco Wahab Guest

    Nene wrote:
    > I want to print (2007-04-18) and (00:05:05) and I want to print where
    > (login_id = 'XSKW0010') which is the next line following this huge
    > select query.
    >
    > Here is the data: (remember, everything from 00004C09 to 'restrict
    > ip' ) is one line.


    If I understood correctly, you want simply
    print [always] the line following your match,
    which contains a date and a time?

    Then something like this should work:


    open( my $fh, '<', shift ) or die "can't open file $!";

    my $flag = 1;
    my $rg = qr/^\w+\s+(\d{4}-\d{2}-\d{2})\s+(\d{2}:\d{2}:\d{2})(?{$flag=0})/;

    while( <$fh> ) {
    if( /$rg/ ) {
    print "$1 $2\n"
    }
    else {
    print unless $flag++
    }
    }

    Regards

    M.
     
    Mirco Wahab, Apr 20, 2007
    #4
  5. Nene <> wrote:

    > Subject: Printing the next line of text of the file



    But you don't what to do that.

    You want to print the next line of text of the array.


    > I wrote a perl script that opens a file. I wrote a regex that
    > captures $1 $2 and prints it to output.



    It is impossible for a regex to print.


    > What I want it to do which I
    > can't figure out is to print the next line (which has a regex that I
    > need to capture as well) under the line that has the the regex but I
    > can't figure it out so far. Any help will be greatly appreciated.



    You need to make a distinction that you seem to be missing.

    There are 2 components to a pattern match, the pattern and the
    string that the pattern is to be matched against.

    The next line does not "have a regex", it has a string (that matches
    a regex).


    > #!/usr/bin/perl -w
    > use strict;
    > use diagnostics;
    >
    >
    > open( FILE, $ARGV[0] ) || die "can't open file!";
    > my @TEST = <FILE>;



    You should not slurp the entire file into an array unless your
    algorithm requires it.

    The solution to your problem is very easy if you had not fallen
    into that bad habit.


    > foreach my $current_line (@TEST) {
    >
    > if ($current_line =~ /^\S+ (\d{4}-\d{2}-\d{2}) (\d{2}:\d{2}:\d{2}) \S+
    > \S+/) {
    > print "$1 $2\n";
    > ## But I also want to print a regex from the line underneath the
    > $current_line ###
    > }
    > }



    while ( my $current_line = <FILE> ) {
    if ($current_line =~ /^\S+ (\d{4}-\d{2}-\d{2}) (\d{2}:\d{2}:\d{2}) \S+ \S+/) {
    print "$1 $2\n";
    my $next_line = <FILE>;
    if ( $next_line =~ /some other regex/ ) {
    ...


    --
    Tad McClellan SGML consulting
    Perl programming
    Fort Worth, Texas
     
    Tad McClellan, Apr 20, 2007
    #5
  6. Nene

    Joe Smith Guest

    Jim Gibson wrote:

    > for( <$fh> ) {
    > if( /$rg_1/ ) {
    > print "$1 $2\n"
    > my $next = <$fh>;


    Won't work. for(<$fh>) reads in the entire file, leaving
    nothing for the next <$fh> to read.

    Use while(<$fh>), not for(<$fh>).

    -Joe
     
    Joe Smith, Apr 20, 2007
    #6
  7. Nene

    -berlin.de Guest

    Mirco Wahab <> wrote in comp.lang.perl.misc:
    > Nene wrote:
    > > I want to print (2007-04-18) and (00:05:05) and I want to print where
    > > (login_id = 'XSKW0010') which is the next line following this huge
    > > select query.
    > >
    > > Here is the data: (remember, everything from 00004C09 to 'restrict
    > > ip' ) is one line.

    >
    > If I understood correctly, you want simply
    > print [always] the line following your match,
    > which contains a date and a time?
    >
    > Then something like this should work:
    >
    >
    > open( my $fh, '<', shift ) or die "can't open file $!";
    >
    > my $flag = 1;
    > my $rg = qr/^\w+\s+(\d{4}-\d{2}-\d{2})\s+(\d{2}:\d{2}:\d{2})(?{$flag=0})/;
    >
    > while( <$fh> ) {
    > if( /$rg/ ) {
    > print "$1 $2\n"
    > }
    > else {
    > print unless $flag++
    > }
    > }


    Uh... that won't print anything unless you initialize $flag to false,
    and even then it'll work for only one pair of lines. Simplifying the
    regex still further:

    my $flag;
    while ( <DATA> ) {
    print if $flag; # the line after a match
    print if $flag = /xxx/; # the matching line
    }

    Anno
     
    -berlin.de, Apr 20, 2007
    #7
  8. Nene

    Mirco Wahab Guest

    -berlin.de wrote:
    > Mirco Wahab <> wrote in comp.lang.perl.misc:
    >> Then something like this should work:
    >> ...
    >> my $rg = qr/^\w+\s+(\d{4}-\d{2}-\d{2})\s+(\d{2}:\d{2}:\d{2})(?{$flag=0})/;
    >>
    >> while( <$fh> ) {
    >> if( /$rg/ ) {
    >> print "$1 $2\n"
    >> }
    >> else {
    >> print unless $flag++
    >> ...

    >
    > Uh... that won't print anything unless you initialize $flag to false,


    I did (didn't I?) - can you spot it?

    > and even then it'll work for only one pair of lines. Simplifying the
    > regex still further:
    >
    > my $flag;
    > while ( <DATA> ) {
    > print if $flag; # the line after a match
    > print if $flag = /xxx/; # the matching line
    > }


    OK, but that a different concept (from mine) and
    seems to be overly verbose:

    my $flag = 1;
    my $rg = qr/^\w+\s+(\d{4}-\d{2}-\d{2})\s+(\d{2}:\d{2}:\d{2})(?{$flag=0})/;
    print /$rg/ ? "$1 $2\n" : $flag++ ? '' : $_ while <$fh> ;

    ;-)

    Regards

    M.
     
    Mirco Wahab, Apr 20, 2007
    #8
  9. Nene

    -berlin.de Guest

    Mirco Wahab <> wrote in comp.lang.perl.misc:
    > -berlin.de wrote:
    > > Mirco Wahab <> wrote in comp.lang.perl.misc:
    > >> Then something like this should work:
    > >> ...
    > >> my $rg = qr/^\w+\s+(\d{4}-\d{2}-\d{2})\s+(\d{2}:\d{2}:\d{2})(?{$flag=0})/;
    > >>
    > >> while( <$fh> ) {
    > >> if( /$rg/ ) {
    > >> print "$1 $2\n"
    > >> }
    > >> else {
    > >> print unless $flag++
    > >> ...

    > >
    > > Uh... that won't print anything unless you initialize $flag to false,

    >
    > I did (didn't I?) - can you spot it?
    >
    > > and even then it'll work for only one pair of lines. Simplifying the
    > > regex still further:
    > >
    > > my $flag;
    > > while ( <DATA> ) {
    > > print if $flag; # the line after a match
    > > print if $flag = /xxx/; # the matching line
    > > }

    >
    > OK, but that a different concept (from mine) and
    > seems to be overly verbose:
    >
    > my $flag = 1;
    > my $rg = qr/^\w+\s+(\d{4}-\d{2}-\d{2})\s+(\d{2}:\d{2}:\d{2})(?{$flag=0})/;
    > print /$rg/ ? "$1 $2\n" : $flag++ ? '' : $_ while <$fh> ;


    Ah... sneaky code insertions :) I didn't give the regex more attention
    than needed to note it's big.

    Code insertions are only there to make it true that "You can do
    everything with a regex".

    Anno
     
    -berlin.de, Apr 20, 2007
    #9
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Jacob Rael
    Replies:
    7
    Views:
    454
    Jacob Rael
    Nov 28, 2006
  2. Deniz Bahar
    Replies:
    2
    Views:
    502
    Andrey Tarasevich
    Mar 9, 2005
  3. kaushikshome
    Replies:
    4
    Views:
    806
    kaushikshome
    Sep 10, 2006
  4. =?ISO-8859-2?Q?Miros=B3aw?= Makowiecki

    Reading of file by next of map file and by next of file descriptor.

    =?ISO-8859-2?Q?Miros=B3aw?= Makowiecki, Jul 10, 2007, in forum: C++
    Replies:
    1
    Views:
    816
    Alf P. Steinbach
    Jul 10, 2007
  5. SRK
    Replies:
    13
    Views:
    612
    BGB / cr88192
    Jan 1, 2010
Loading...

Share This Page