http://www.perlmonks.org?node_id=987498

andalou has asked for the wisdom of the Perl Monks concerning the following question:

I'm using perl 5.12.4 on windows 7.
I have files which have the word canción in their filenames and I want
to change it to poesía. How can I do it? If I use the following script,
canción will be converted to poesía and not poesía.

#!perl use utf8; my $directory = '.'; opendir (MYHANDLE , $directory) || die "Cant open directory :$!\n"; my @files = readdir MYHANDLE; closedir MYHANDLE; foreach (@files) { my $original = $_; s/canción/poesía/; rename "$directory\\$original", "$directory\\$_"; }

The filenames are of the form:

canción de la vida.txt canción de la naturaleza.txt canción 和平之歌.txt ...

Many thanks in advance,

Cesar

Replies are listed 'Best First'.
Re: renaming filenames
by GrandFather (Saint) on Aug 15, 2012 at 05:45 UTC

    Perl punts on Unicode for most OS related interactions because different OSs handle Unicode differently, or not at all (see When Unicode Does Not Happen).

    For Windows you can call the Win32 API MoveFile function to get the job done:

    use strict; use warnings; use utf8; use Win32::API; my $moveFile = Win32::API->new("Kernel32", MoveFileW => 'PP', "I"); my $to = 'poesía'; my $from = 'canción'; $moveFile->Call(Encode::encode("UTF-16LE", $from), Encode::encode("UTF-16LE", $to));
    True laziness is hard work

      It doesn't work. It only works if the values of $from and $to don't
      contain any accents, as in: $from=song and $to=poem but it doesn't work
      if they contain accents.

      The editor I'm using is vim, so I'm saving my files in utf-8
      encoding.

        The sample script shown worked as expected for me using Windows 7 and Perl 5.10.1 (ActiveState MSWin32-x86-multi-thread build). In what way doesn't it work for you?

        True laziness is hard work
Re: renaming filenames
by tobyink (Canon) on Aug 15, 2012 at 05:52 UTC

    Check that your script really is saved in UTF-8. What editor are you using to write your script? Does it offer a choice of encoding when you save files?

    perl -E'sub Monkey::do{say$_,for@_,do{($monkey=[caller(0)]->[3])=~s{::}{ }and$monkey}}"Monkey say"->Monkey::do'
Re: renaming filenames
by Anonymous Monk on Aug 15, 2012 at 06:44 UTC

      I'm always getting the following error:

      Undefined subroutine &Errno::ERROR_FILE_EXISTS called at C:/Perl/site/ +lib/Win32/Unicode/Error.pm line 31.

        With what?

Re: renaming filenames
by pvaldes (Chaplain) on Aug 16, 2012 at 09:24 UTC
    ls * | perl -nle'$in=$_; s/canción/Poesía/; $out=$_; rename($in,$out)if!-e$out'

    Works for me. Details in this node

    Corrected -e$n: thanks to remiah

      Maybe trivial thing to say,
      rename($in,$out) if !-e $out
      doesn't it ?

        I'm using perl 5.12.4 on windows 7.
        Your code doesn't work in windows.