目录中有以下文件列表:
#是的,这些是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和命令行都会抛出错误,指出在具有rename
function的string处Permission denied
。
如何解决这个问题,伙计们?
UPD。 软件:
Perl的readdir
使用一个传统的接口(“ANSI”),因为它只能处理由unix遗留的字节组成的文件名。
“ANSI”接口使用称为代码页的单字节字符编码。 你的系统的代码页是1251 ,它不提供编码“ä”的方法,所以包含“ä”的文件名不能由readdir
返回。
您需要避免使用“ANSI”接口( FindFirstFileA
)并访问FindFirstFileW
。 这将提供UTF-16le的文件名,您可以传递给Win32API :: File的MoveFileExW
。 Win32 :: Unicode :: Dir的open
+ fetch
就是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();
您正在阅读目录,就好像它是UTF-8一样,但是您确实是在使用Windows-1252编码。 失去use open qw(...)
,它应该工作。
你有访问“rename.pl”吗? 你可以做
perl rename.pl "s/^(\d\d)/$1./" *flac
?