Suppose you have a list of files like this:
a.v0 a.v1 a.v2 a.v3 a.v4 a.v5
It would be nice to "recycle" or rotate the filenames such that the result is:
a.v0 a.v1 a.v2 a.v3 a.v4
That is, files in the list are renamed to their predecessors, while the first file in the list is removed. This is a maintanance tool for a poorman's versioning system.
I've written such a thing in Perl. Here is the code:
#!/usr/bin/perl -w # Revision rotator # # Takes filenames of the form *.vi, where i is a positive integer, # and operates on them such that the file with the smallest # value of i is unlinked, and successors (as ordered by the numerical # values of i) are renamed to their predecessors. Example: # # Input filenames: a.v5 a.v4 a.v1 a.v3 a.v2 a.v0 # # Will perform: # # unlink a.v0 # mv a.v1 a.v0 # mv a.v2 a.v1 # mv a.v3 a.v2 # mv a.v4 a.v3 # mv a.v5 a.v4 # # Functions correctly for i>9. # # Author: Michal Guerquin # March, 2005 use strict; my @files = @ARGV; ## make sure files are valid ".v#" files for my $f (@files) { if (not $f =~ /\.v(\d+)$/) { die "Invalid file specified: $f\n"; } } ## sort filenames by their trailing number @files = sort ( { $a=~/(\d+)$/;my $aa=$1;$b=~/(\d+)$/;my $bb=$1; $aa <=> $bb } @ARGV); ## a list of cmds to execute my @actions; ## for each file in the (sorted) list for (my $i=0; $i<=$#files; $i++) { ## if it's the first one, unlink it if ($i == 0) { push @actions, "unlink " . $files[$i]; } ## otherwise, extract the name and version number, ## subtract 1 from v. number, and move file accordingly elsif ($i>0) { $files[$i] =~ /(.*)\.v(\d+)$/; my $fname = $1; my $newver = $2 - 1; push @actions, "mv " . $files[$i] . " " . $fname . ".v" . $newver; ## alternative behavior: ## this moves to the files "predecessor". so in a ## list of files a.v5, a.v7, a.v8, actions will ## be: ## ## mv a.v7 a.v5 ## mv a.v8 a.v7 ## ## push @actions, "mv " . $files[$i] . " " . $files[$i-1]; } } ## announce what will happen print "Will perform the following commands:\n\n"; foreach my $a (@actions) { print " " . $a . "\n"; } print "\nOkay to proceed? (y/n) "; my $p =; $p = lc($p); chomp($p); if ($p ne "y") { die "Aborted.\n"; } ## execute each command, printing status as it happens foreach my $a (@actions) { print "system(\"" . $a . "\");\n"; system($a); }
revrotate.pl
, and have a set of files a.v0
through a.v5
:
$ ls a* a.v0 a.v1 a.v2 a.v3 a.v4 a.v5 $ revrotate.pl a* Will perform the following commands: unlink a.v0 mv a.v1 a.v0 mv a.v2 a.v1 mv a.v3 a.v2 mv a.v4 a.v3 mv a.v5 a.v4 Okay to proceed? (y/n) y system("unlink a.v0"); system("mv a.v1 a.v0"); system("mv a.v2 a.v1"); system("mv a.v3 a.v2"); system("mv a.v4 a.v3"); system("mv a.v5 a.v4"); $ ls a* a.v0 a.v1 a.v2 a.v3 a.v4
I've found a really good use for this. Maybe you will too!
https://michal.guerquin.com/revrotate.html
, updated 2005-03-08 01:01 EST