[Samba] linux -> windows special characters in filenames problems

Haro de Grauw bin at harodegrauw.net
Tue Apr 28 18:50:34 GMT 2009


# Haro de Grauw (me at harodegrauw.net), 28-04-1988
# Windows illegal characters for file names are: < > : " / \ | ? *
# Of these, two are usable in Linux: : ?
# This script renames all files and (sub)folders from current directory to replace
# : and ? with underscore _, in order to enable samba sharing or copy to FAT drive.
# Based on a script by iman_saleh retrieved from http://www.perlmonks.org/?node_id=658908
# With thanks (iman_saleh really did most of the work on this).

# WARNING: filenames will be overwritten without warning. So, if you already have a file
# named "my_file" and a file named "my:file", the second one will be renamed to "my_file"
# due to character substitution, and will overwrite the original "my_file"!!!

# WARNING: this script will run in the CURRENT directory and all subdirectories. God help
# you if you run this script from the wrong place.

use Cwd; # module for finding the current working directory
$|=1;    # turn off I/O buffering

# This subroutine takes the name of a directory and recursively scans down
# the filesystem from that point looking for files with : or ? in their name

sub ScanDirectory{
    my ($workdir) = shift;
    my ($startdir) = &cwd; # keep track of where we began
    print "\nScanning folder $workdir\n";

    chdir($workdir) or die "Unable to enter dir $workdir:$!\n";
    opendir(DIR, ".") or die "Unable to open $workdir:$!\n";
    my @names = readdir(DIR) or die "Unable to read $workdir:$!\n";

    foreach my $name (@names){
        next if ($name eq ".");  # ignore files "." and "..", which are just pointers to current and parent directories, resp.
        next if ($name eq ".."); #

        $newName = $name;
        $newName =~ s/\?/\_/g;
        $newName =~ s/:/\_/g;
        unless ($newName eq $name) {print "  Renaming $name to $newName\n";}
        $result = rename($name, $newName) or die "cannot rename $name to $newName:$!\n"; # note that this will rename directories as well as files

        if (-d $newName){             # is this a directory?
            &ScanDirectory($newName); # if yes, then scan it!

    chdir($startdir) or die "Unable to change to dir $startdir:$!\n";

print "\nDone.\n\n";

More information about the samba mailing list