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 Chriss Miller on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Help needed for a beginner

Status
Not open for further replies.

jos11

Technical User
Joined
Aug 29, 2006
Messages
5
Location
CA
I’m a beginner on Perl programming and I spend a few hours to find some information about how to read 2 file and parse them together

The first file is the log file containing some values, the second file is the reference file used to find the variable and compare the value on the log file (my reference file will have the compare operator)

Only the last value of the log file is important for me, the last value will be used for the output.

The output should indicate the values that I look for (from the reference file) and also an indication of pass or fail depending on the compare value of both variables

Thanks in advance for you help.

Log file looks like this:

StartMarker
<Step Name>
<Locals> Variable Value
aa 0.00e+000
bb 0.00e+000
cc 0.00e+000
dd 0.00e+000
ee 0.00e+000
ff 0.00e+000
dd 0.00e+000
ee 0.00e+000
ff 0.00e+000
gg 0.00e+000
hh 0.00e+000
ii 0.00e+000
jj 0.00e+000
<FileGlobals> Variable Value
<StationGlobals> Variable Value
EndMarker
StartMarker
<Step Name>
<Locals> Variable Value
aa 0.00e+000
bb 0.00e+000
cc 0.00e+000
dd 0.00e+000
ee 0.00e+000
ff 1.00e+005
dd 0.00e+000
ee 0.00e+000
ff 0.00e+000
gg 0.00e+000
hh 0.00e+000
ii 0.00e+000
jj 0.00e+000
<FileGlobals> Variable Value
<StationGlobals> Variable Value
EndMarker
StartMarker
<Step Name>
<Locals> Variable Value
aa 0.00e+000
bb 0.00e+000
cc 0.00e+000
dd 0.00e+000
ee 0.00e+000
ff 0.00e+000
dd 1.00e+006
ee 0.00e+000
ff 5.38e+003
gg 0.00e+000
hh 0.00e+000
ii 0.00e+000
jj 0.00e+000
<FileGlobals> Variable Value
<StationGlobals> Variable Value
EndMarker



Reference file look like this:

dd >= 6.00e-006
ff <= 1.00e-006
 
I was planning to use some array to store the information and process them. Another approach is to do a pattern matching and value compare …

Not sure wish one is the best approach for my project.

open (REFERENCE,"<$reference.txt")
|| die "Can't open $reference.txt $!";
open (LOG,"<$log.txt")
|| die "Can't open $log.txt $!";

# Build an assoc. array (%reference)
while (<REFERENCE>) {
($var,$operator,$value) = split;
}
close REFERENCE;

# Build an assoc. array (%log):
while (<lOG>) {
chop; # remove line that are not part of the data
($var,$value) = split;
}
close LOG;
 
Are you looking for the last instance of the line that starts with 'dd' and the line that starts with 'ff' in the log file?


dd 1.00e+006
ff 5.38e+003

and then you want to do something like this using the reference file?


1.00e+006 >= 6.00e-006 = true/false
5.38e+003 <= 1.00e-006 = true/false


how big is the log file? A few lines? Thosuands of lines? Millions of lines?
 
Yes I’m looking for the last instance of “dd” and “ff” into the log file. Btw the reference file can change that’s why I use file to store those entries.

Exactly I need to perform the following operation:
1.00e+006 >= 6.00e-006 = true/false
5.38e+003 <= 1.00e-006 = true/false

The log file can be a few thousands, from 250,000 to 750,000 of lines.

Thanks !

 
If it's last values you want, a hash would be the way to travel.

Code:
while (<LOG>) {
   chomp $_;
   if (index ($_, "<") != -1) { # assuming you haven't played with $[ in which case it's 0
     ($var,$value) = split /\s+/, $_;
     $log{$var}=$value;
   }
}
close LOG;
while (<REFERENCE>) {
  ($var, $op, $value) = split /\s+/, $_;
  $result=eval ($log{$var} $op $value);
  if ($result == 1) {   #will otherwise return a null string
    print "$log{$var} $op $value is TRUE\n";
  } else {
    print "$log{$var} $op $value is FALSE\n";
  }
close REFERENCE;
HTH
HTH

Paul
------------------------------------
Spend an hour a week on CPAN, helps cure all known programming ailments ;-)
 
If it's the last values in the file I would try using File::Bidirectional or File::ReadBackwards (neither is a core module though). You can also use Tie::File which enables you to read a file backwards, although I am unclear as to how efficient that is with Tie::File.

Code:
use File::Readbackwards;

#change the file names as needed
my $log = 'log.txt';
my $reference = 'reference.txt';

my $log_line = '';
my %log = ();
my $bw = File::ReadBackwards->new( $log ) or
                        die "can't read '$log' $!" ;

while( defined( $log_line = $bw->readline ) ) {
   if ($log_line =~ /^(dd |ff )/) {
      my ($k,$v) = split(/\s+/,$log_line);
      $log{$k}=$v;
      last if (keys %log == 2);
   }
}

# I borrowed from Pauls code 
# but corrected a couple of things

open (REFERENCE,"<$reference") or
                    die "Can't open '$reference' $!";
while (<REFERENCE>) {
  my ($var, $op, $value) = split(/\s+/);
  my $result = [b]eval "$log{$var} $op $value";[/b]
  if ($result == 1) {   #will otherwise return a null string
    print "$log{$var} $op $value is TRUE\n";
  } else {
    print "$log{$var} $op $value is FALSE\n";
  }
[b]}[/b]  
close REFERENCE;
 
Thanks everyone

I will try this and give you an update on this

Many thanks again !
 
I got this errors

Can't locate File/Readbackwards.pm in @INC (@INC contains: /etc/perl /usr/local/
lib/perl/5.8.4 /usr/local/share/perl/5.8.4 /usr/lib/perl5 /usr/share/perl5 /usr/
lib/perl/5.8 /usr/share/perl/5.8 /usr/local/lib/site_perl .) at compare_2.pl lin
e 7.
 
You have to install the File::Readbackwards module.
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top