You could slurp the whole file; then one regex will do:
local $/;
while (<>) {
while (/^name\n-+\n(.*)/mg) {
# stuff you want is in "$1"
}
}
update: added "g" flag.
-- Chip Salzenberg, Free-Floating Agent of Chaos | [reply] [d/l] |
Heres one way you could do it (I am making a lot of assumptions, so the regexes will probably need tweaking): use strict;
use warnings;
while ( <DATA> ) {
#if it is in between the lines starting with name
#and ending with a line of numbers and spaces
#note that the between in inclusive so it includes
#those two lines.
if ( /^name/ .. /^[\d ]+$/ ) {
#don't want the next line of dashes or name line
next if ( /name/ or /^---------------------------$/ );
print $_;
}
}
__DATA__
bunch
name
---------------------------
23 23 23 23 23 23 23 23 23
of
name
---------------------------
25 25 25 25 25 25 25 25 25
other
worthless
name
---------------------------
28 28 28 28 28 28 28 28 28
unnecessary and annoying
noise
1 2 3 4 9 8
name
---------------------------
29 29 29 29 29 29 29 29 29
__END__
23 23 23 23 23 23 23 23 23
25 25 25 25 25 25 25 25 25
28 28 28 28 28 28 28 28 28
29 29 29 29 29 29 29 29 29
-enlil
| [reply] [d/l] |
If your file is too large to slurp, and performance is an issue--when is it ever not :)-- you might consider this technique.
Demo
Output
D:\Perl\test>258244
1 23 4.5 678e9
1 23 4.5 678e9
1 23 4.5 678e9
Examine what is said, not who speaks.
"Efficiency is intelligent laziness." -David Dunham
"When I'm working on a problem, I never think about beauty. I think only how to solve the problem. But when I have finished, if the solution is not beautiful, I know it is wrong." -Richard Buckminster Fuller
| [reply] [d/l] [select] |
When you find what you are looking for, read the next couple lines and dump the one's you don't want.
while (<>){
if (/name/)
{
<>; #reads the line of dashes
$whatIwant=<>;#grabs the next line "This is What I..."
print $whatIwant;
}
}
| [reply] [d/l] |
Chip's idea is not a bad approach, unless you're dealing with a really big data file (as in megabytes, more than the amount of available RAM). If so, maybe it's the case (as suggested by your example) that your data is structured in multi-line records, with a consistent string that marks the end of each record.
To pull an entire multi-line record into $_ in a single read iteration, play with the "$/" (record-separator) variable:
$/ = '---------End Data--------\n'; # or whatever
while (<>) {
if (/name\s+-+\s+(.*)/) { # "\s+" matches "\n", "(.*)" doesn't
$whatIwant = $1;
# do something with $whatIwant...
}
}
| [reply] [d/l] |