#!/usr/bin/perl # Copyright 2004-7 Vlado Keselj http://www.cs.dal.ca/~vlado sub help { print <<"#EOT" } # move-merge moves directory structures onto one target directory, version $VERSION # # Move and merge directories into the destination directory, with file # renaming. The script is useful in incremental backups with rsync. # # Usage: find-equal-files [switches] [destinationdir] [dirs] # -h Print help and exit. # -v Print version of the program and exit. # # An illustrative Scenario: Assume that we are making regular backups # of the directory /home/user into /backup/user while saving the old # files into directory /backup/user-old/041201-08:54:51, where # 041201-08:54:51 is a time-stamp-named directory with the structure # similar to the previous /backup/user directory. When this is # periodically repeated, the directory /backup/user-old/ accumulates a # lot of directories and it needs to be cleaned periodically. # Before cleaning, it may be useful to merge the tagged directories # with: move-merge m 0* #EOT use strict; use vars qw( $VERSION $Dest $Src $Label ); $VERSION = sprintf "%d.%d", q$Revision: 1.3 $ =~ /(\d+)/g; use Getopt::Std; use vars qw($opt_v $opt_h); getopts("vh"); if ($opt_v) { print "$VERSION\n"; exit; } elsif ($opt_h || $#ARGV < 1) { &help(); exit; } $Dest = shift; while (@ARGV) { $Label = $Src = shift; $Label =~ s/\/$//; $Label =~ s/\//-/g; die if $Label eq ''; &merge($Dest, $Src); rmdir $Src or die; } sub merge { my $dest = shift; my $src = shift; if (!-d $dest) { die "Dir does not exist: $dest" } if (!-d $src) { die "Dir does not exist: $src" } local (*DIR); opendir(DIR, $src); foreach (readdir(DIR)) { if ($_ eq '.' or $_ eq '..') { next } elsif ( -d "$src/$_" && ! -l "$src/$_" ) { if ( -e "$dest/$_" && !-d "$dest/$_") { my $cnt = 1; while ( -e "$dest/$_-$cnt") { ++$cnt } rename("$dest/$_", "$dest/$-$cnt"); } if (!-d "$dest/$_") { mkdir("$dest/$_", (((stat "$src/$_")[2] |0700)& 0777)) or die} &merge("$dest/$_", "$src/$_"); rmdir "$src/$_" or die "cannot remove ($src/$_)"; } else { if (-e "$dest/$_" && (! -d "$dest/$_" || -l "$dest/$_")) { my $cnt = 1; while (-e "$dest/$_-$cnt") { ++$cnt } rename("$dest/$_", "$dest/$_-$cnt"); } if (!-d "$dest/$_") { mkdir("$dest/$_", (((stat "$src/$_")[2] | 0700 )& 0777)) or die } my $destname = "$dest/$_/$Label"; if (-e $destname) { my $cnt = 1; while ( -e "$destname-$cnt") { ++$cnt } $destname = "$destname-$cnt"; } rename("$src/$_", $destname); } } }