Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > Perl > Perl Misc > Printing the next line of text of the file

Reply
Thread Tools

Printing the next line of text of the file

 
 
Nene
Guest
Posts: n/a
 
      04-19-2007
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 ###
}
}

 
Reply With Quote
 
 
 
 
Mirco Wahab
Guest
Posts: n/a
 
      04-19-2007
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
 
Reply With Quote
 
 
 
 
Nene
Guest
Posts: n/a
 
      04-19-2007
On Apr 19, 6:58 pm, Mirco Wahab <wahab-m...@gmx.de> 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-1 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 =

 
Reply With Quote
 
Mirco Wahab
Guest
Posts: n/a
 
      04-19-2007
Nene wrote:
> I want to print (2007-04-1 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.
 
Reply With Quote
 
Tad McClellan
Guest
Posts: n/a
 
      04-20-2007
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
 
Reply With Quote
 
Joe Smith
Guest
Posts: n/a
 
      04-20-2007
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
 
Reply With Quote
 
anno4000@radom.zrz.tu-berlin.de
Guest
Posts: n/a
 
      04-20-2007
Mirco Wahab <wahab-> wrote in comp.lang.perl.misc:
> Nene wrote:
> > I want to print (2007-04-1 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
 
Reply With Quote
 
Mirco Wahab
Guest
Posts: n/a
 
      04-20-2007
wrote:
> Mirco Wahab <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.
 
Reply With Quote
 
anno4000@radom.zrz.tu-berlin.de
Guest
Posts: n/a
 
      04-20-2007
Mirco Wahab <wahab-> wrote in comp.lang.perl.misc:
> wrote:
> > Mirco Wahab <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
 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
Read a file line by line and write each line to a file based on the5th byte scad C++ 23 05-17-2009 06:11 PM
Reading of file by next of map file and by next of file descriptor. =?ISO-8859-2?Q?Miros=B3aw?= Makowiecki C++ 1 07-10-2007 02:46 AM
Simple text parsing gets difficult when line continues to next line Jacob Rael Python 7 11-28-2006 10:03 PM
How to read a text file line by line and remove some line kaushikshome C++ 4 09-10-2006 10:12 PM
CurrentElement->next = CurrentElement->next->next (UNDEFINED?) Deniz Bahar C Programming 2 03-09-2005 12:45 AM



Advertisments
 



1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57