Printing the next line of text of the file

N

Nene

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 ###
}
}
 
M

Mirco Wahab

Nene said:
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
 
N

Nene

Nene said:
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 =
 
M

Mirco Wahab

Nene said:
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.
 
T

Tad McClellan

Nene said:
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/ ) {
...
 
J

Joe Smith

Jim said:
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
 
A

anno4000

Mirco Wahab said:
Nene said:
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
 
M

Mirco Wahab

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.
 
A

anno4000

Mirco Wahab said:
I did (didn't I?) - can you spot it?


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
 

Ask a Question

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

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,754
Messages
2,569,525
Members
44,997
Latest member
mileyka

Latest Threads

Top