From 41781058476180e060339e9065eeee18365d6c38 Mon Sep 17 00:00:00 2001 From: Ward Wouts Date: Tue, 31 Jul 2001 11:50:31 +0000 Subject: [PATCH] regels wisselen kan nu ook --- mvwrap/mvwrap | 127 ++++++++++++++++++++++++++++++++++++++++---------- 1 file changed, 103 insertions(+), 24 deletions(-) diff --git a/mvwrap/mvwrap b/mvwrap/mvwrap index 3de8061..fe693ae 100755 --- a/mvwrap/mvwrap +++ b/mvwrap/mvwrap @@ -1,8 +1,9 @@ #!/usr/bin/perl -w # -# Scriptje om een editor op de inhoud van directories los te laten. -# Makkelijker dan 6000 keer move met de hand doen. +# Script to let an editor loose on a directory listing +# Much easier than doing 6000 moves by hand +# I think it's relatively safe now # (C) 2001 Ward Wouts # @@ -19,9 +20,10 @@ while ( defined ($filename = readdir(DIRHANDLE)) ) { push @dir, "$filename\n"; } closedir(DIRHANDLE); -@source= sort @dir; +@source = sort @dir; if ($DEBUG) { print @source; } + # make tempfiles and install handler to remove them do { $target_name = tmpnam() } until $target = IO::File->new($target_name, O_RDWR|O_CREAT|O_EXCL); @@ -30,41 +32,62 @@ END { unlink($target_name) or die "Couldn't unlink $target_name: $!" } foreach (@source) { print $target $_; } - close ($target); -$editor = defined $ENV{EDITOR} ? $ENV{EDITOR} : "vi"; -@editor = ("$editor", "$target_name"); -system(@editor) == 0 - or die "System @editor failed: $?"; +&edit($target_name); -open $target, $target_name; -while (<$target>) { - push @target, $_; -} +open $target, $target_name or die "Couldn't open tempfile: $target_name: $!"; +@target = <$target>; close ($target); + if ($DEBUG) { print @target; } unless ( scalar(@source) == scalar(@target) ) { die "Aborting. Source and target list don't have the same number of lines.\n"; } -if (&check_unique(@target)) { +if ( &check_unique(@target) ) { die "Aborting. You're trying to move multiple files to the same name.\n"; } -$i=0; -while ( $i < scalar(@source) ) { - $source=$source[$i]; - chomp($source); - $target=$target[$i]; - chomp($target); - unless ( $source eq $target ) { - if ($DEBUG) { print "mv $source $target\n"; } - move("$source", "$target") - or die "move failed: $!"; +# if it's unsafe to move files directly, move the unsafe ones to a +# temporary file first +if (@unsafe = &check_safety(\@source, \@target)) { + &safety_belt(\@unsafe, \@source); +} + +# final move +&move_files(\@source, \@target); + +# call EDITOR or vi with filename +sub edit { + my $filename = shift; + $editor = defined $ENV{EDITOR} ? $ENV{EDITOR} : "vi"; + @editor = ("$editor", "$filename"); + system(@editor) == 0 + or die "System @editor failed: $?"; +} + +# moves files from the names in one array to the names in another array +# must be called like: +# move_files(\@source, \@target) +sub move_files { + my ($from, $to) = @_; + my($i, $source, $target); + $i=0; + while ( $i < scalar(@$from) ) { + $source=$from->[$i]; + chomp($source); + $target=$to->[$i]; + chomp($target); + unless ( $source eq $target ) { + if ($DEBUG) { print "mv $source $target\n"; } + move("$source", "$target") + or die "move failed: $!"; + } + $i++; } - $i++; + return 1; } # returns 0 if all entries in @target_list are unique. 1 if not. @@ -78,3 +101,59 @@ sub check_unique (@target_list){ } return 0; } + +# compares one array of file names to another, making sure files +# can be moved safely without overwriting each other +# must be called like: +# check_safety(\@source, \@target) +# returns an array of unsafe line numbers +sub check_safety { + my ($from, $to) = @_; + my($i, $j, $source, $target, @danger); + $i=0; + while ( $i < scalar(@$from) ) { + $source=$from->[$i]; + chomp($source); + $j=0; + while ( $j < scalar(@$to) ) { + $target=$to->[$j]; + chomp($target); + if (($source eq $target) && ($i != $j)) { + push @danger, $i; + } + $j++; + } + $i++; + } + return @danger; +} + +# generate random filename, which does not exist +sub rand_file { + my (@chars, $filename, $exists); + @chars=( "A" .. "Z", "a" .. "z", 0 .. 9); + $exists = 1; + while ($exists) { + $filename = join("", @chars[ map { rand @chars } ( 1 .. 8 ) ]); + $exists = -e $filename; + } + + return $filename; +} + +# moves files to a random filename and updates +# the source array +# must be called like: +# safety_belt(\@unsafe, \@source) +sub safety_belt { + my ($unsafe, $source) = @_; + my($filenr, $filename, $rand); + foreach $filenr (@$unsafe) { + $filename = $source->[$filenr]; + chomp $filename; + $rand = &rand_file; + move("$filename", "$rand") + or die "move failed: $!"; + $source->[$filenr] = "$rand\n"; + } +}