Re: Extracting Data from a second line
by Roy Johnson (Monsignor) on Feb 16, 2006 at 16:03 UTC
|
This will print the red line line and the one following:
while (<DATA>) {
print if /red line/..././;
}
__DATA__
A red line is found
at location 2.5 4.5
A Blue line is found
at location 2.6 4.5
A red line is found
at location 2.67 4.56
The red arc is found
at location 2.5 4.5
and if you don't want the red line line, make it
print if (/red line/..././) =~ /E/;
Caution: Contents may have been coded under pressure.
| [reply] [d/l] [select] |
Re: Extracting Data from a second line
by brian_d_foy (Abbot) on Feb 16, 2006 at 19:15 UTC
|
In these situations, I come up with a way to read one "record" at a time. You can do several things to get back all of the information for one record with one operation.
For instance, write a function to read two lines at once (adding appropriate checks I don't cover here).
while( defined( my $record = get_record( $fh ) )
{
# ...
}
sub get_record
{
my $fh = shift;
join '', scalar <$fh>, scalar <$fh>;
}
Sometimes preprocessing the data works better. You take your data file and join the appropriate lines. It's even better if you can track down the guy who can change the output at the source. :) Once it's all on one line, life is easy.
A red line is found at location 2.5 4.5
I've also found alternate delimiters useful. If you have to have a newline between the two interesting lines, maybe you can have a form feed (or something else) as the separator between records. Then you can set $/ to the record separator and read records instead of lines.
A little database is a little more fancy than that, and more useful if you have to use the same data file over and over. Process the file once and store it in something such as a DBM::Deep file. Now lookups are as easy as using a hash, and you only have to process the file once.
| [reply] [d/l] [select] |
Re: Extracting Data from a second line
by duff (Parson) on Feb 16, 2006 at 15:49 UTC
|
my ($x,$y,$redline);
while (<FILE>) {
if ($redline) {
($x,$y) = /at location (\S+) (\S+)/;
print "$x $y\n";
}
$redline = /red line/;
}
Vary the details as needed. $redline is set to a true value when ever the pattern matches (and a false value when it doesn't match) so that on the next iteration of the loop, you'll be able to capture the location information.
| [reply] [d/l] [select] |
Re: Extracting Data from a second line
by tweetiepooh (Hermit) on Feb 16, 2006 at 15:54 UTC
|
My solution is different again. No error checking etc. Assumes all data as given. open(FH,"file");
while( <FH> ) {
if (/red line/) {
process(<FH>);
}
}
Note this will read the lines below other 'keys' but will just pass them by.
Not the most elegant or efficient but it does work. | [reply] [d/l] |
|
|
| [reply] [d/l] [select] |
Re: Extracting Data from a second line
by kwaping (Priest) on Feb 16, 2006 at 15:42 UTC
|
#!/usr/bin/perl
use strict;
use warnings;
use Data::Dumper::Simple;
read DATA, my $text, 163; #<- manually grabbed size of DATA just for t
+his example
my @matches = ($text =~ /red line.*?location\s+(\d+\.\d+\s+\d+\.\d+)/s
+g);
print Dumper(@matches);
__DATA__
A red line is found
at location 2.5 4.5
A Blue line is found
at location 2.6 4.5
A red line is found
at location 2.67 4.56
The red arc is found
at location 2.5 4.5
| [reply] [d/l] |
|
|
Replace 163 with -s DATA.
| [reply] [d/l] [select] |
|
|
If I'm working with a regular filehandle, I always use -s to get the length to read, but unfortunately that doesn't work here. -s DATA will give you the length of the entire file, Perl code included, not just the part after __DATA__.
Update: With that stated, I do realize it wouldn't hurt anything to supply a bigger number than required as the third argument to read.
| [reply] [d/l] [select] |
|
|
|
|
|
Re: Extracting Data from a second line
by davidrw (Prior) on Feb 16, 2006 at 15:47 UTC
|
and yet another approach ...
while(<FILE>){
next unless /^(?:A|The) (.*) is found$/;
my $item = $1;
my $next_line = <FILE>;
next unless $next_line =~ /^at location (.*)/;
my $location = $1; # needs chomp'ing??
printf "'%s' is as [%s]\n", $item, $location; # or shove into some
+ data structure
}
| [reply] [d/l] |
Re: Extracting Data from a second line
by ikegami (Patriarch) on Feb 16, 2006 at 15:36 UTC
|
my $i = 0;
while (<FILE>) {
next if ++$i % 2;
print;
}
Here, $i can be replaced with $.:
while (<FILE>) {
next if $. % 2;
print;
}
Or use next with a toggle:
my $toggle = 0;
while (<FILE>) {
next if $toggle ^= 1;
print;
}
By the way,
#!usr/bin/perl
is wrong. You must remove the leading space, and you must make the path absolute (or else it will only work form the root):
#!/usr/bin/perl
Update: I didn't read your post close enough. The above didn't answer your question. A solution would be:
for (;;) {
last if not defined (my $line1 = <FILE>);
last if not defined (my $line2 = <FILE>);
next if not $line1 =~ /red line/;
print($line1, $line2);
}
| [reply] [d/l] [select] |
Re: Extracting Data from a second line
by GrandFather (Saint) on Feb 17, 2006 at 04:28 UTC
|
use strict;
use warnings;
local $/ = "A red line is found\n";
while (<DATA>) {
print "Red line $1" if /(at location[^\n]*\n)/;
}
__DATA__
A red line is found
at location 2.5 4.5
A Blue line is found
at location 2.6 4.5
A red line is found
at location 2.67 4.56
The red arc is found
at location 2.5 4.5
Prints:
Red line at location 2.5 4.5
Red line at location 2.67 4.56
DWIM is Perl's answer to Gödel
| [reply] [d/l] [select] |
Re: Extracting Data from a second line
by BrowserUk (Patriarch) on Feb 17, 2006 at 05:40 UTC
|
Read two lines at a time and concatenate them. Use /s on the regex to allow '.' to match the newline.
#! perl -slw
use strict;
m[red line.*location (\S+) (\S+)\n]s and print "($1, $2)"
while $_ = <DATA> . <DATA>;
__DATA__
A red line is found
at location 2.5 4.5
A Blue line is found
at location 2.6 4.5
A red line is found
at location 2.67 4.56
The red arc is found
at location 2.5 4.5
Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
Lingua non convalesco, consenesco et abolesco. -- Rule 1 has a caveat! -- Who broke the cabal?
"Science is about questioning the status quo. Questioning authority".
In the absence of evidence, opinion is indistinguishable from prejudice.
| [reply] [d/l] |
|
|
Thanks to ALL of those that replied,
these insights were exactly what I needed
to get the information I wanted.
RCP
| [reply] |