views:

55

answers:

2

I am completely new to perl and have just been learning it. I came across this script I need to run that has some network Tstat trace data. However, I get an error 'Cannot parse date.'

The code that generates this is here

foreach my $dir (@trace_dirs) {
 undef @traces;
 opendir(DIR, $dir) || die "Can't open dir: $dir \n";
 @traces = grep { /.out$/ && -d "$dir/$_" } readdir(DIR);
 foreach my $trace (@traces) {
  $trace =~ /^(\d\d)_(\d\d)_(\d\d)_(\w\w\w)_(\d\d\d\d)/;
  $trace_date=&ParseDate("$3/$4/$5 $1:$2") || die "Cannot parse date \n";
  $traces{$trace_date} = $trace;
  $trace_dir{$trace_date} = $dir;
 }
 closedir DIR;
}

can some tell me what this code is looking for?

+2  A: 

When you run into problems like this, throw yourself a bone by looking at the data you are trying to play with. Make sure that the value in $trace is what you expect and that the date string you create is what you expect:

 print "Trace is [$trace]\n";
 if( $trace =~ /^(\d\d)_(\d\d)_(\d\d)_(\w\w\w)_(\d\d\d\d)/ ) {
     my $date = "$3/$4/$5 $1:$2";
     print "date is [$date]\n";
     $trace_date= ParseDate( $date ) || die "Cannot parse date [$date]\n";
     }

I'm guessing that the value in $4, which apparently is a string like 'Jan', 'Feb', and so on, isn't something that ParseDate likes.

Note that you should only use the capture variables after a successful pattern match, lest they be left over from a different match.

brian d foy
+1  A: 

However, I get an error 'Cannot parse date.'

You get the error due to the line:

$trace =~ /^(\d\d)_(\d\d)_(\d\d)_(\w\w\w)_(\d\d\d\d)/;

The script expects that all files in the directory with extension .out have proper timestamps in the beginning of their names. And the line of the script lack any error handling.

Try adding some check here, e.g.:

unless($trace =~ /^(\d\d)_(\d\d)_(\d\d)_(\w\w\w)_(\d\d\d\d)/) {
   warn "WRN: Malformed file name: $trace\n";
   next;
}

That checks if the file name matches, and if it doesn't, warning would be printed and it would be skipped.

Alternatively you can also add the check to the grep {} readdir() line:

@traces = grep { /.out$/ && /^(\d\d)_(\d\d)_(\d\d)_(\w\w\w)_(\d\d\d\d)/ && -d "$dir/$_" } readdir(DIR);

to filter out misplaced .out files (hm, actually directories) before they reach the loop which calls the ParseDate function.

Dummy00001