Beefy Boxes and Bandwidth Generously Provided by pair Networks
Perl: the Markov chain saw

Re: Batch file renaming - on identical name, keep only most recent file, based on dates

by shadowsong (Pilgrim)
on Dec 19, 2019 at 00:45 UTC ( #11110370=note: print w/replies, xml ) Need Help??

in reply to Batch file renaming - on identical name, keep only most recent file, based on dates

For posterity,

Here's another approach that avoids loading the entire list in memory and also neglects the use of -M (it relies specifically on the naming convention of the candidate target files in OP's description).

hauxex points out some caveats using the -M file tests that could render its use unreliable. Gabor Szabo also highlights its weirdness.

Sharing the code below to illustrate the idea behind the computation of the psuedo_mtime field which was used for comparisons.

#!/usr/bin/perl use strict; use warnings FATAL => 'all'; use Getopt::Long qw ( :config no_ignore_case bundling ); use Pod::Usage qw ( pod2usage ); # parse options my (%opt,$dir); GetOptions(\%opt, "help|h", "verbose|v", "test|t", "version", "directo +ry|d=s" => \$dir) || pod2usage(-verbose => 0); pod2usage(-verbose => 1, -exitval => 1) if $opt{'help'}; pod2usage(-verbose => 99, -exitval => 0, -sections => [qw(VERSION)]) i +f $opt{'version'}; pod2usage(-verbose => 0, -message => "$0: No directory given\n") if ! +$dir; my @AGE_RATIONALISER = (31104000,2592000,86400,3600,60,1); # yy,mm,dd, +hh,mm,ss converted to secs my $processed_hash_ref; opendir DH, $dir or die "Couldn't open directory $dir: $!"; chdir $dir; # filetests using relative path while ($_ = readdir (DH)) { next unless -f $_ && m/^\d_\d{4}_\d\d?_\d\d?_\d\d?_\d\d?_\d\d?_table/i; my @old_fname = split /_/; my $new_fname = join ('_', @old_fname[ 7..11 ]); my $psuedo_mtime = 0; # divine a fake but consistent mtime f +rom the filename $psuedo_mtime += $old_fname[$_+1] * $AGE_RATIONALISER[$_] for (0.. +$#AGE_RATIONALISER); # already seen a more recent file with the name we're # planning to use? skip current file next if defined $processed_hash_ref->{$new_fname} && $processed_hash_ref->{$new_fname}->{AGE} > $psuedo_mtime; # file safe to be renamed... for now $processed_hash_ref->{$new_fname}->{OLDNAME} = $_; $processed_hash_ref->{$new_fname}->{AGE} = $psuedo_mtime; } closedir DH; # now proceed to rename items map { print "[!] rename $processed_hash_ref->{$_}->{OLDNAME} to $_\n" if + $opt{'verbose'}; rename $processed_hash_ref->{$_}->{OLDNAME}, $_ unless $opt{'test' +}; } keys %$processed_hash_ref; __END__ =head1 NAME =over 4 - file renaming utility =back =head1 SYNOPSIS =over 4 [-t | --test] {-d log-file-directory} [-v | --verbose] {-d log-file-directory} [-h | --help] [--version] =back =head1 OPTIONS =over 4 =item B<-t, --test> Test run - no renaming takes place - effectively a simulation =item B<-v, --verbose> Verbose - printout of files to be renamed =item B<-h, --help> Help - prints this manual =back =head1 DESCRIPTION B<This program> will read the given directory and rename a contingent of the files within said directory. Files to be renamed that share the same target name - will have only the most recent one renamed. =head1 AUTHORS Shadowsong =head1 VERSION 0.0.1-beta =cut
  • Comment on Re: Batch file renaming - on identical name, keep only most recent file, based on dates
  • Select or Download Code

Log In?

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: note [id://11110370]
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others exploiting the Monastery: (4)
As of 2022-01-24 17:08 GMT
Find Nodes?
    Voting Booth?
    In 2022, my preferred method to securely store passwords is:

    Results (64 votes). Check out past polls.