in reply to Compare script

#use strict; $comparetime="0"; sub compare; $Clinrxdir="D:\\StoreAccess\\shared\\sup shared\\"; opendir(DIR,$Clinrxdir); @Files= readdir(DIR); closedir(DIR); foreach $cpupdate (@Files){ if($cpupdate =~ m/\s*cp_/i){ my $m_time = (stat($Clinrxdir.$cpupdate))[9]; my ($i_wday, $i_month, $day, $year) = (localtime($m_time))[6,4,3,5]; compare($m_time); print "Timestamp for " . $cpupdate . " " . $m_time ."\n"; } } print "This is a test of file = " . $file . "\n"; print $file; system("pause"); sub compare($){ local( $string ) = shift; if($comparetime > $string){ $file=$cpupdate;} else{$comparetime=$string;} }
I noticed some error's i made with my variable names, I corrected these, it now outputs the oldest timestamp, but does not update the name of the file to go with it.. for instance my timetamp was for file 4 but it was still listing file 1 as the output

Replies are listed 'Best First'.
Re^2: Compare script
by stevieb (Canon) on Aug 29, 2009 at 18:43 UTC

    I went through the code, making changes mostly for practice. It is *untested*. Hopefully the comments are of use. Furthermore, hopefully others can criticize me for my deficiencies:

    #use strict; # don't disable strict. Period. # you are only using $comparetime within the compare() function # If you define it here, then it should be passed to the sub as # a parameter my $comparetime="0"; # sub compare; # no need for this my $Clinrxdir="D:\\StoreAccess\\shared\\sup shared\\"; opendir(DIR,$Clinrxdir); my @Files= readdir(DIR); closedir(DIR); for my $cpupdate (@Files){ if($cpupdate =~ m/\s*cp_/i){ my $m_time = (stat($Clinrxdir.$cpupdate))[9]; # what does a print() say about $m_time here? my ($i_wday, $i_month, $day, $year) = (localtime($m_time))[6,4 +,3,5]; # why are you breaking $m_time up. Depending on what you want to d +o, # it may be easiest to simply compare $m_time as an int my $comparison = compare($orig_mtime, $cmp_mtime $cupupdate); print "Timestamp for " . $cpupdate . " " . $m_time ."\n"; } } # I'm lost as to where $file comes from here... print "This is a test of file = " . $file . "\n"; print $file; system("pause"); sub compare(){ my ( $orig_mtime, $cmp_mtime, $cpuupdate ) = @_; if($cmp_mtime > $orig_mtime){ my $file = $cpupdate; } else{ #else{$comparetime=$string;} # it looks like you are trying to cause more than one side # effect with your subroutine, as opposed to focusing on providing # a single return. Personally, I've learned that mixing function # programming with global data will lead to bugs that are very # difficult to track down. # if you want to set $comparetime to $string, you should do it # outside of this routine, after you've collected up compare() # result } }

    Steve

Re^2: Compare script
by graff (Chancellor) on Aug 30, 2009 at 05:13 UTC
    You say you want to "compare file time stamps", but you don't say what the goal is. Based on looking at your "compare" sub, it would seem that you are trying to identify the most recent file in a directory.

    First, you have to remember that readdir returns every directory entry, including "." and ".." (which are directories, as you must know, and which could often, by coincidence, be dated more recently than any data file in the directory).

    If you want to pick the most recent entry in a directory (not including "." or ".."), then try something like this:

    #!/usr/bin/perl use strict; use File::Spec; my $Usage = "Usage: $0 pathname\n"; die $Usage unless ( @ARGV == 1 and -d $ARGV[0] ); my $path = shift; opendir( D, $path ) or die "$path: $!\n"; my %files; for my $file ( grep !/^.{1,2}$/, readdir D ) { my $filepath = File::Spec->catfile( $path, $file ); my $file_age = -M $filepath; $files{$file_age} = $file; } my @age_order; push @age_order, $files{$_} for ( sort {$a<=>$b} keys %files ); print "Newest file in $path is: $age_order[0]\n";
    In that version, you just have to provide the directory path as a command line arg; it uses -M (as suggested by toolic below) to get the age of each file (as a floating point value, in days) relative to the time when the script starts running.