[linux-l] Dateinamen rekursiv umwandeln

Ralf Baerwaldt 1bar at gmx.de
Mi Mär 28 11:13:53 CEST 2007


> Ich will das betreffende /home/ jetzt auf einem USB-Laufwerk sichern. Dabei 
> treten die beiden folgenden Probleme auf:
> 
> A.) Manche Namen sind für das Laufwerk (verhält sich windowsmäßig) doppelt 
> vorhanden (ichbineinedatei und Ichbineinedatei)
> 
> B.) Durch die verschiedenen Locale sind bei manchen Dateien die Namen 
> verhunzt. Die bekannten beiden hochkantstehenden Vierecke ...
> 
> Hat einer eine Idee, die das Homeverzeichnis rekursive durchsucht und alle 

Versuchs mal mit folgendem Programm. Aber Achtung:

DAS PROGRAMM ZERSTOERT DATEN !
BITTE VORHER EINE DATENSICHERUNG DURCHFUEHREN !

Gruss Ralf

------------------------------ 8< ------------------------------
#!/usr/bin/perl -w 
#
# vi: ts=4 ai ic :

use strict;

sub usage {
	warn "$0 ".join(" ", at ARGV)."\n";
	print STDERR <<EOT;
	
	$0 DIRNAME
		Program searches DIRNAME for all files and directories
		having a letter not in [a-z0-9_.- ].
		Capital letters are switched to lower, all other violating
		letters are switched to underline.
		A number is added to the name, if an entry already exists.

	This program doesn't pay attention to the old FAT 8.3 format !

EOT

	die "Abbort";
	
};

sub standard ($) {
	my $RS_ORIG=shift;
	my $NEW = lc($$RS_ORIG);

	$NEW =~ tr/- a-z0-9._\//_/c;
	return $NEW;
};


usage unless ($#ARGV >= 0 );

my $DEBUG		= 1;
my $ROOTDIR		= $ARGV[0];
my $SUBDIR		= $#ARGV == 0 ? 0 : 1;

warn "opening $ROOTDIR" if ($DEBUG & 4);
opendir(ROOT, $ROOTDIR) or die "Can't open '$ROOTDIR' or it is not a directory: $!";
while($_=readdir(ROOT)) {
	next if ( /^\.{1,2}$/ );	# skip "." and ".." entries
	my $ENTRY = "$ROOTDIR/$_";
	my $NEW_NAME;
	my $CNT = 0;	# number to be appended to standardizied ENTRY-Name

	warn "process $ENTRY" if ($DEBUG & 2);

	my $STANDARD = standard(\$ENTRY);

	warn "standard: '$ENTRY' -> '$STANDARD'\n" if ($DEBUG & 2);
	next if ($STANDARD eq $ENTRY);		# keep good names

	$NEW_NAME = $STANDARD;

	#	check if entry exists
	while ( -e $NEW_NAME ) {
		$NEW_NAME = $STANDARD . '-' . ++$CNT;
	};

	#	rename
	print STDERR "'$ENTRY' -> '$NEW_NAME'\n" if ($DEBUG & 1);
	rename $ENTRY, $NEW_NAME;

	#	do subdirs
	-d $NEW_NAME and system($0, $NEW_NAME, 1);
};

# warn "$0 $ARGV[0] done";

print "done\n" unless ($SUBDIR);
exit 0;
------------------------------ >8 ------------------------------




Mehr Informationen über die Mailingliste linux-l