如何使用Perl的File :: Copy复制名称中包含特殊字符的文件?

时间:2010-09-21 16:10:25

标签: perl file special-characters

我正在尝试将一个位置的所有文件复制到另一个位置并使用File::Copy模块和copy命令,但现在我面临的问题是我的文件是名称有special character,其ascii值为&#253,但在unix文件系统中,它存储为?,所以我的问题是copy or move command在复制时会考虑这些带有特殊字符的文件或者搬到另一个地方, 如果现在那么可能会解决这个问题呢?

注意:我无法在unix中创建包含特殊字符的文件,因为特殊字符会替换为?而我无法在Windows中执行此操作,因为在Windows上,特殊字符会被编码值替换就像我&#253的情况一样?

my $folderpath = 'the_path';
open my $IN, '<', 'path/to/infile';
my $total;
while (<$IN>) {
    chomp;
    my $size = -s "$folderpath/$_";
    print "$_ => $size\n";
    $total += $size;
}
print "Total => $total\n";

礼貌:RickF Answer

任何建议都将受到高度赞赏。

参考问题Perl File Handling Question

3 个答案:

答案 0 :(得分:3)

作为解决方法我可以建议将所有不受支持的字符转换为支持的字符。这可以通过多种方式完成。例如,您可以使用URI::Escape

use URI::Escape;
my $new_file_name = uri_escape($weird_file_name);

<强>更新

以下是我能够通过其uft-8名称复制文件的方法。我在Windows上。我用Win32::GetANSIPathName来获取短文件名。然后它被复制了很好:

use File::Copy;
use URI::Escape;
use Win32;

use utf8; ## tell perl that source code is in utf-9
use strict;
use warnings;

my $test_file = "IBMýSoftware.txt";
my $from_file = Win32::GetANSIPathName($test_file); ## get "short" name of file
my $to_file   = uri_escape($test_file); ## name with special characters escaped

printf("copy [%s] -> [%s]\n", $from_file, $to_file);
copy($from_file, $to_file);

在Windows上将所有文件复制到新名称之后,您就可以毫无问题地在Linux上使用它们。

以下是关于utf-8文件打开的一些提示:

答案 1 :(得分:3)

角色253是ý。我想在你的Unix系统上没有设置locale,或者只有最原始的后退语言环境有效,这就是你看到替换字符的原因。如果我正确猜测,解决方案是简单地将语言环境设置为某种东西,最好设置为UTF-8语言环境,因为它可以处理所有字符,而Perl甚至不应该进入问题。

> cat 3761218.pl
use utf8;
use strict;
use warnings FATAL => 'all';
use autodie qw(:all);

my $file_name = '63551_106640_63551 IBMýSoftware Delivery&Fulfillment(Div-61) Data IPS 08-20-2010 v3.xlsm';
open my $h, '>', $file_name;

> perl 3761218.pl
> ls 6*
63551_106640_63551 IBMýSoftware Delivery&Fulfillment(Div-61) Data IPS 08-20-2010 v3.xlsm
> LANG=C ls 6* # temporarily cripple locale so that the problem in the question is exhibited
63551_106640_63551 IBM??Software Delivery&Fulfillment(Div-61) Data IPS 08-20-2010 v3.xlsm
> locale | head -1 # show which locale I have set
LANG=de_DE.UTF-8

答案 2 :(得分:0)

以下脚本对我有效:

#!/usr/bin/perl

use strict; use warnings;
use autodie;

use File::Copy qw( copy );
use File::Spec::Functions qw( catfile );

my $fname = chr 0xfd;

open my $out, '>', catfile($ENV{TEMP}, $fname);
close $out;

copy catfile($ENV{TEMP}, $fname) => catfile($ENV{HOME}, $fname);