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