2

目录中有以下文件列表:

  1. 01 出生 - 被赞美 - Kissed.flac
  2. 02 万岁.flac
  3. 03 你知道了.flac
  4. 04 在这个洞里.flac
  5. 05 Wälsungenblut.flac
  6. ... N. 0N 文件名

#是的,这些是 Oomph 的歌曲!

并在 Perl 上执行以下程序:

use warnings;
use strict;
use utf8;
use open qw( :encoding(UTF-8) :std );

my @dirnames;

while ( (my $dirname = <>) =~ /\S/ ) {
    chomp($dirname);
    push (@dirnames, $dirname);
}

foreach my $dirname (@dirnames) {
    opendir (DIR, $dirname);
    while ( my $file = readdir(DIR) ) {
        if(length($file)>5) {
            print $file , "\n";
            my $newfile;

            $newfile = substr($file, 0, 2);
            $newfile .= '.';
            $newfile .= substr($file, 2);

            rename ($dirname . '\\' . $file, $dirname . '\\' . $newfile) or die $!;
        }
    }
    closedir DIR;
}

获取目录列表并通过在数字后添加点来重命名其中的文件。

程序在所有文件上都可以正常工作,但是当它尝试重命名文件名中带有变音符号的文件时,Windows PowerShell 和命令行都会在带有函数Permission denied的字符串处抛出错误。rename

各位大侠怎么解决这个问题?

UPD。软件:

  • 视窗 8 x64
  • ActiveState ActivePerl 1601 (Perl 5.16)
4

3 回答 3

3

Perlreaddir使用传统接口(“ANSI”),因为它只能处理由字节组成的文件名,因为它具有 unix 传统。

“ANSI”接口使用称为代码页的单字节字符编码。您系统的代码页是1251,并且它不提供编码“ä”的方法,因此无法返回包含“ä”的文件名readdir

您需要避免使用此“ANSI”接口 ( FindFirstFileA) 并获得对FindFirstFileW. 这将提供 UTF-16le 格式的文件名,您可以将其传递给Win32API::FileMoveFileExW. Win32::Unicode::Diropen+fetch就是这样做的。

这是一种令人沮丧的状况。我一直想解决它,但这将是一个广泛的项目。

use utf8;
use Win32 qw( );
BEGIN {
   binmode(STDOUT, ':encoding(cp'.Win32::GetConsoleOutputCP().')');
   binmode(STDERR, ':encoding(cp'.Win32::GetConsoleOutputCP().')');
}

use strict;
use warnings;
use feature qw( say );
use open ':encoding(UTF-8)';

use Encode              qw( encode );
use Win32::Unicode::Dir qw( mvtreeW );
use Win32API::File      qw( MoveFileExW );

my $dir_qfn = '.';

my $wdir = Win32::Unicode::Dir->new();
$wdir->open($dir_qfn)
   or die("Can't open $dir_qfn: ".$wdir->error());

for ($wdir->fetch()) {
   next if /^\.\.?\z/;
   next if length() <= 5;

   say;

   my $o_fn = $_;
   s/^..\K/./s;
   my $n_fn = $_;

   MoveFileExW(
      encode('UTF-16le', "$dir_qfn/$o_fn\0"),
      encode('UTF-16le', "$dir_qfn/$n_fn\0"),
      0,  # or MOVEFILE_REPLACE_EXISTING
   )
      or die("Can't rename $o_fn to $n_fn: $^E\n");
}

$wdir->close();
于 2013-06-19T08:28:00.240 回答
0

您正在读取目录,就好像它是 UTF-8 一样,但您实际上是 Windows-1252 编码。失去use open qw(...)它,它应该工作。

于 2013-06-18T17:54:08.267 回答
-2

您可以访问“rename.pl”吗?你可以做

perl rename.pl "s/^(\d\d)/$1./" *flac

?

于 2013-06-18T19:18:43.747 回答