Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations strongm on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

perl newbie File manipulation

Status
Not open for further replies.

martialartsdrum

Programmer
Oct 21, 2011
1
Hi All,
I am a relative newbie to perl and running into a syntax issue.

I need to open a file, search for a certain flag, then extract and manipulate data until another flag is reached.

pseudo code:

open file
while not EOF
read line
if line contains search_flag
while line does not contain end_flag
manipulate data

What I am running into, is that the perl code loops in the while loop waiting for the end_flag and it is never reached because we are not reading from the file from within the loop.

$file = $ARGV[0]; # Name the file
open(INPUTFILE, $file) || die "couldn't open the file!";
@lines = <INPUTFILE>;
foreach (@lines)
{
my($line) = $_;
chomp($line);
if ($line =~ /Processing table/)
{
while ($line !~ /99: VolumeTable/)
{
# here is where I need to manipulate the data
# and increment line.
}
}
}

SO.. the quesion is. How is this accomplished?

thanks

John
 
Hi

While you already slurped in the entire file, I would use [tt]grep[/tt] :
Perl:
[navy]@lines[/navy] [teal]=[/teal] [green][i]<DATA>[/i][/green][teal];[/teal]
[b]print[/b] [b]grep[/b] [teal]{[/teal] [green][i]/start/../end/[/i][/green] [teal]}[/teal] [navy]@lines[/navy][teal];[/teal]

__DATA__
one
two
three start
four
five
six
seven end
eight
nine
ten
If you prefer the loop, better use a single one and a flag variable :
Perl:
[b]my[/b] [navy]@lines[/navy] [teal]=[/teal] [green][i]<DATA>[/i][/green][teal];[/teal]
[b]chomp[/b] [navy]@lines[/navy][teal];[/teal]
[b]foreach[/b] [b]my[/b] [navy]$line[/navy] [teal]([/teal][navy]@lines[/navy][teal])[/teal] [teal]{[/teal]
  [navy]$inside[/navy] [teal]=[/teal] [purple]1[/purple] [b]if[/b] [navy]$line[/navy] [teal]=~[/teal] [b]m[/b][fuchsia]/start/[/fuchsia][teal];[/teal]
  [b]if[/b] [teal]([/teal][navy]$inside[/navy][teal])[/teal] [teal]{[/teal]
[gray]#   here is where I need to manipulate the data[/gray]
    [b]print[/b] [green][i]"$line\n"[/i][/green][teal];[/teal]
  [teal]}[/teal]
  [navy]$inside[/navy] [teal]=[/teal] [purple]0[/purple] [b]if[/b] [navy]$line[/navy] [teal]=~[/teal] [b]m[/b][fuchsia]/end/[/fuchsia][teal];[/teal]
[teal]}[/teal]
If you reverse the statements setting the flag, you will get only the inner lines, without the delimiting lines :
Perl:
[b]my[/b] [navy]@lines[/navy] [teal]=[/teal] [green][i]<data>[/i][/green][teal];[/teal]
[b]chomp[/b] [navy]@lines[/navy][teal];[/teal]
[b]foreach[/b] [b]my[/b] [navy]$line[/navy] [teal]([/teal][navy]@lines[/navy][teal])[/teal] [teal]{[/teal]
  [navy]$inside[/navy] [teal]=[/teal] [purple]0[/purple] [b]if[/b] [navy]$line[/navy] [teal]=~[/teal] [b]m[/b][fuchsia]/end/[/fuchsia][teal];[/teal]
  [b]if[/b] [teal]([/teal][navy]$inside[/navy][teal])[/teal] [teal]{[/teal]
[gray]#   here is where i need to manipulate the data[/gray]
    [b]print[/b] [green][i]"$line\n"[/i][/green][teal];[/teal]
  [teal]}[/teal]
  [navy]$inside[/navy] [teal]=[/teal] [purple]1[/purple] [b]if[/b] [navy]$line[/navy] [teal]=~[/teal] [b]m[/b][fuchsia]/start/[/fuchsia][teal];[/teal]
[teal]}[/teal]
If you want two loops, then you will have to change to two [tt]for[/tt]s and use a common loop control variable :
Perl:
[b]my[/b] [navy]@lines[/navy] [teal]=[/teal] [green][i]<DATA>[/i][/green][teal];[/teal]
[b]chomp[/b] [navy]@lines[/navy][teal];[/teal]
[b]for[/b] [teal]([/teal][b]my[/b] [navy]$i[/navy][teal]=[/teal][purple]0[/purple][teal],[/teal] [navy]$l[/navy][teal]=[/teal]scalar [navy]@lines[/navy][teal];[/teal] [navy]$i[/navy][teal]<[/teal][navy]$l[/navy][teal];[/teal] [navy]$i[/navy][teal]++)[/teal] [teal]{[/teal]
  [b]if[/b] [teal]([/teal][navy]$lines[/navy][teal][[/teal][navy]$i[/navy][teal]][/teal] [teal]=~[/teal] [b]m[/b][fuchsia]/start/[/fuchsia][teal])[/teal] [teal]{[/teal]
    [b]for[/b] [teal](;[/teal] [navy]$i[/navy][teal]<[/teal][navy]$l[/navy][teal];[/teal] [navy]$i[/navy][teal]++)[/teal] [teal]{[/teal]
[gray]#     here is where I need to manipulate the data[/gray]
      [b]print[/b] [green][i]"$lines[$i]\n"[/i][/green][teal];[/teal]
      [b]last[/b] [b]if[/b] [navy]$lines[/navy][teal][[/teal][navy]$i[/navy][teal]][/teal] [teal]=~[/teal] [b]m[/b][fuchsia]/end/[/fuchsia][teal];[/teal]
    [teal]}[/teal]
  [teal]}[/teal]
[teal]}[/teal]


Feherke.
 
This is how I would do that:
Code:
$file = $ARGV[0];
open(INPUTFILE,$file)||die"couldn't open the file!";
while(<INPUTFILE>){
  last if/Processing table/;
}
while(<INPUTFILE>){
  last if/99: VolumeTable/;
#          manipulate the data 
}

Franco
: Online engineering calculations
: Magnetic brakes for fun rides
: Air bearing pads
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top