View Full Version : trouble parsing .txt file
shadkeene
06-14-2007, 08:12 PM
I'm working on a program to parse individual bits of weather data from a text file (eventually will be from a webpage but starting with .txt for now). I've been able to parse one bit of data with the following loop. However, I'm not sure how to parse other data in the same loop since I'm using $line and using "next" which confuses me a bit in how I could stay in the loop...or should I just close the file and open again? If I did the latter, would it make the program slow? I was trying to use "if $line =~ m/pattern/" initially but couldn't get it to work so I used the "if not equal to, then next" method. Thanks for any help,
#!/perl/bin/perl -w
use CGI qw(:standard);
use CGI::Carp qw(warningsToBrowser fatalsToBrowser);
use Fcntl qw(:flock :seek);
use strict;
print header;
print start_html("Gradients");
open(FH, "C:/perl-scripts/Data/BarkerPWTest.txt") #open barker extrapolated NAM data .txt file
or &dienice("couldn't open output file: $!");
print "<h2>PW</h2>";
while (my $line = <FH>) { #reads through each line of model data
if ($line !~ m/^ Precip/) { #if line isn't Precip Water line, then will skip to next line
next;
}
print "$line<br>"; #prints PW fcst data string
my $data = $line; #places PW fcst data into string $data
my @PWdata = split(/\s+/, $data); #splits string of PW fcst data into individual elements
print "$PWdata[6]";
}
close (FH);
print end_html;
sub dienice {
my($errmsg) = @_;
print "<h2>Error</h2>\n";
print "<p>$errmsg</p>\n";
print end_html;
exit;
}
javabits
06-14-2007, 09:15 PM
try the following:
foreach $line (<FH>) { #reads through each line of model data
if ($line !~ m/^ Precip/) {
#if line isn't Precip Water line, then will skip to next line
print "$line<br>"; #prints PW fcst data string
my $data = $line; #places PW fcst data into string $data
my @PWdata = split(/\s+/, $data); #splits string of PW fcst data into individual elements
print "$PWdata[6]";
}
}
semper fi...
KevinADC
06-14-2007, 09:35 PM
there should be no need to close and open the file more than once. How you parse out bits of data depends on how the lines are formatted. You can use regexp or the split() function, both of which you are already doing. There is also substr() which is good for fixed length records but can be used for varaible length records too.
shadkeene
06-15-2007, 05:28 PM
Thanks folks, I'll give it a try today and let you know how it goes...
shadkeene
06-16-2007, 08:44 PM
Hi,
I was able to parse different data in the same loop...however, now I'd like to extract data from two files, using two while loops after opening each .txt file...then do arithmetic with the data I extracted. The problem is that when I reference a variable in the second while loop that I initialized in the first while loop, the script doesn't recognize it. To be more clear, there is a number value for $SLPdataSFO[6] that I extracted in the first while loop, and I'd like to subtract that value from $SLPdataSAC[6], which I extracted in the second while loop. I tried to make it a global variable at the beginning by using "our @SLPdataSFO = ();" to make it a global variable, but no luck there. Any ideas? Thanks for your help....the error I receive is as follows with the script after that.
Shad
Global symbol "@SLPdataSFO" requires explicit package name at c:\perl-scripts\BarkerRegParser.cgi line 54.
Execution of c:\perl-scripts\BarkerRegParser.cgi aborted due to compilation errors.
#!/perl/bin/perl -w
use CGI qw(:standard);
use CGI::Carp qw(warningsToBrowser fatalsToBrowser);
use Fcntl qw(:flock :seek);
use strict;
print header;
print start_html("Gradients");
open(FH, "C:/perl-scripts/Data/BarkerSFOtest.txt") #open barker SFO extrapolated NAM data .txt file
or &dienice("couldn't open output file: $!");
print "<h2>PW</h2>";
while (my $line = <FH>) { #reads through each line of model data
if ($line =~ m/^ Mean/) { #finds line with sealevel pressure
print "$line<br>";
my $SFOdataSLP = $line; #places $line into new string called $data SLP
my @SLPdataSFO = split(/\s+/, $SFOdataSLP); #splits $data SLP string into individual elements between whitespace
print "$SLPdataSFO[6]<br>";
print "$SLPdataSFO[4]<br>";
my $SLPchgSFO = $SLPdataSFO[6] -= $SLPdataSFO[4]; #subtracts 12hr SLP from 0hr SLP
print "$SLPchgSFO<br>";
my $roundf = sprintf("%1.1f", $SLPchgSFO);
print "$roundf<br>";
}
elsif ($line =~ m/^ Precip/) { #if line isn't Precip Water line, then will skip to next line
print "$line<br>";
my $dataPW = $line;
my @PWdata = split(/\s+/, $dataPW);
print "$PWdata[6]<br>";
}
}
close (FH);
open(FH, "C:/perl-scripts/Data/BarkerSACtest.txt") #open barker SFO extrapolated NAM data .txt file
or &dienice("couldn't open output file: $!");
while (my $line = <FH>) { #reads through each line of model data
if ($line =~ m/^ Mean/) { #finds line with mean sealevel pressure
print "$line<br>";
my $SACdataSLP = $line; #places $line into new string called $SACdataSLP
my @SLPdataSAC = split(/\s+/, $SACdataSLP); #splits $SACdataSLP string into individual elements between whitespace
my $SACSFOgrad12 = $SLPdataSFO[6] -= $SLPdataSAC[6]; #subtracts SFO from SAC 12-hr fcst sealevel pressure
print "$SACSFOgrad12";
}
}
close (FH);
print end_html;
sub dienice {
my($errmsg) = @_;
print "<h2>Error</h2>\n";
print "<p>$errmsg</p>\n";
print end_html;
exit;
}
KevinADC
06-16-2007, 09:16 PM
What you are doing will work if the file is only one line long because you redeclare a new array each time you do this:
my @SLPdataSFO = split(/\s+/, $SFOdataSLP); #splits $data SLP string into individual elements between whitespace
so only the last line of a mulitple line file ends up populating the @SLPdataSFO array (or the first line if it's a one line file).
You probably want to use the push() function to build up an array of data from the file (or files) that you would use to do later calculations on. Hard to say without seeing the files or knowing the relationship between them.
shadkeene
06-16-2007, 09:45 PM
Kevin,
Here's the data I'm working with...in order that they're being opened. This might give you a better idea of what I'm working with. The @SLPdataSFO is only one line long...I'm just cutting it up into elements so I can index them. But for whatever reason, I can't refer back to @SLPdataSFO once I'm outside of that loop.
Station ID: KSFO Lat: 39.48 Long: -119.77
NAM Model Run: 12Z JUN 9, 2007
Forecast Hours: 0hr 6hr 12hr 18hr 24hr 30hr 36hr
Sfc Prs(mb): 865.3 864.0 863.9 865.1 864.2 862.8 861.7
Mean SLP (mb): 1012.0 1008.3 1006.3 1009.8 1010.3 1007.0 1003.9
2m agl Tmp (F): 52.0 71.0 75.0 63.9 58.9 73.3 73.2
2m agl Dewpt(F): 39.2 37.7 40.5 39.2 34.4 33.0 43.7
2m agl RH (%): 61 29 28 39 39 22 33
10m agl Dir: 275 188 260 265 182 231 252
10m agl Spd(kt): 1 4 10 6 3 10 16
6hr Precip (in): 0.00 0.00 0.00 0.00 0.00 0.00 0.00
AccumPrecip(in): 0.00 0.00 0.00 0.00 0.00 0.00 0.00
Sfc CAPE (J/kg): 0.0 0.0 3.1 0.0 0.0 0.0 36.7
Sfc CINH (J/kg): 0.0 0.0 -7.8 0.0 0.0 -0.5 -66.6
Precip H20 (in): 0.47 0.48 0.55 0.58 0.54 0.57 0.71
Station ID: KSAC Lat: 39.48 Long: -119.77
NAM Model Run: 12Z JUN 9, 2007
Forecast Hours: 0hr 6hr 12hr 18hr 24hr 30hr 36hr
Sfc Prs(mb): 865.3 864.0 863.9 865.1 864.2 862.8 861.7
Mean SLP (mb): 1014.0 1009.3 1010.3 1011.8 1012.3 1007.0 1003.9
2m agl Tmp (F): 52.0 71.0 75.0 63.9 58.9 73.3 73.2
2m agl Dewpt(F): 39.2 37.7 40.5 39.2 34.4 33.0 43.7
2m agl RH (%): 61 29 28 39 39 22 33
10m agl Dir: 275 188 260 265 182 231 252
10m agl Spd(kt): 1 4 10 6 3 10 16
6hr Precip (in): 0.00 0.00 0.00 0.00 0.00 0.00 0.00
AccumPrecip(in): 0.00 0.00 0.00 0.00 0.00 0.00 0.00
Sfc CAPE (J/kg): 0.0 0.0 3.1 0.0 0.0 0.0 36.7
Sfc CINH (J/kg): 0.0 0.0 -7.8 0.0 0.0 -0.5 -66.6
0-3km Hel(J/kg): 72.3 17.1 6.3 -56.0 33.1 31.4 19.2
Precip H20 (in): 0.47 0.48 0.55 0.58 0.54 0.57 0.7
FishMonger
06-16-2007, 10:58 PM
But for whatever reason, I can't refer back to @SLPdataSFO once I'm outside of that loop.The reason is that you're using the strict pragma and you've declared the @SLPdataSFO array to be private to the if block within the while loop.
You need to assign $SLPdataSFO[6] to a global scalar and use that scalar instead of the array in the second while loop.
KevinADC
06-16-2007, 10:58 PM
declare the array at the beginning of the script so you can use it all through the script:
use CGI qw(:standard);
use CGI::Carp qw(warningsToBrowser fatalsToBrowser);
use Fcntl qw(:flock :seek);
use strict;
my @SLPdataSFO = ();
print header;
print start_html("Gradients");
open(FH, "C:/perl-scripts/Data/BarkerSFOtest.txt") #open barker SFO extrapolated NAM data .txt file
or &dienice("couldn't open output file: $!");
print "<h2>PW</h2>";
while (my $line = <FH>) { #reads through each line of model data
if ($line =~ m/^ Mean/) { #finds line with sealevel pressure
print "$line<br>";
my $SFOdataSLP = $line; #places $line into new string called $data SLP
@SLPdataSFO = split(/\s+/, $SFOdataSLP); #splits $data SLP string into individual elements between whitespace
print "$SLPdataSFO[6]<br>";
print "$SLPdataSFO[4]<br>";
my $SLPchgSFO = $SLPdataSFO[6] -= $SLPdataSFO[4]; #subtracts 12hr SLP from 0hr SLP
print "$SLPchgSFO<br>";
my $roundf = sprintf("%1.1f", $SLPchgSFO);
print "$roundf<br>";
}
elsif ($line =~ m/^ Precip/) { #if line isn't Precip Water line, then will skip to next line
print "$line<br>";
my $dataPW = $line;
my @PWdata = split(/\s+/, $dataPW);
print "$PWdata[6]<br>";
}
}
close (FH);
open(FH, "C:/perl-scripts/Data/BarkerSACtest.txt") #open barker SFO extrapolated NAM data .txt file
or &dienice("couldn't open output file: $!");
while (my $line = <FH>) { #reads through each line of model data
if ($line =~ m/^ Mean/) { #finds line with mean sealevel pressure
print "$line<br>";
my $SACdataSLP = $line; #places $line into new string called $SACdataSLP
my @SLPdataSAC = split(/\s+/, $SACdataSLP); #splits $SACdataSLP string into individual elements between whitespace
my $SACSFOgrad12 = $SLPdataSFO[6] -= $SLPdataSAC[6]; #subtracts SFO from SAC 12-hr fcst sealevel pressure
print "$SACSFOgrad12";
}
}
close (FH);
print end_html;
sub dienice {
my($errmsg) = @_;
print "<h2>Error</h2>\n";
print "<p>$errmsg</p>\n";
print end_html;
exit;
shadkeene
06-17-2007, 01:49 AM
Thanks! That helped a lot and I learned something there.
Shad
vBulletin® v3.8.2, Copyright ©2000-2012, Jelsoft Enterprises Ltd.