5

csvファイルに基づいて画像の名前をバッチで変更およびコピーするスクリプトに取り組んでいます。csv は、列 1: 古い名前と列 2: 新しい名前で構成されます。csv ファイルを perl スクリプトの入力として使用して、古い名前をチェックし、新しい名前を使用してコピーを新しいフォルダーに作成したいと考えています。私が抱えている(と思う)問題は、画像に関係しています。それらには ß などの utf8 文字が含まれています。スクリプトを実行すると、次のように出力されます:

Unsuccessful stat on filename containing newline at C:/Perl64/lib/File/Copy.pm line 148, <$INFILE> line 1.
Copy failed: No such file or directory at X:\Script directory\correction.pl line 26, <$INFILE> line 1.

私はそれが Binmode utf8 と関係があることを知っていますが、単純なスクリプトを試しても (ここで見ました: How can I output UTF-8 from Perl? ):

use strict;
use utf8;
my $str = 'Çirçös';
binmode(STDOUT, ":utf8");
print "$str\n";

次のように表示されます: Ãirþ÷s

これは私のスクリプト全体です。どこが間違っているのか誰か説明してもらえますか? (私はものをテストしていたので、それは最もきれいなコードではありません)。

use strict;
use warnings;
use File::Copy;
use utf8;

my $inputfile  = shift || die "give input!\n";
#my $outputfile = shift || die "Give output!\n";

open my $INFILE,  '<', $inputfile   or die "In use / not found :$!\n";
#open my $OUTFILE, '>', $outputfile  or die "In use / not found :$!\n";

binmode($INFILE, ":encoding(utf8)");

#binmode($OUTFILE, ":encoding(utf8)");

while (<$INFILE>) {
s/"//g;
my @elements = split /;/, $_;

my $old = $elements[1];
my $new = "new/$elements[3]";
binmode STDOUT, ':utf8';
print "$old | $new\n";

copy("$old","$new") or die "Copy failed: $!";
#copy("Copy.pm",\*STDOUT);

#   my $output_line = join(";", @elements);
#    print $OUTFILE $output_line;
#print "\n"
}

close $INFILE;
#close $OUTFILE;

exit 0;
4

1 に答える 1

3

プロセスのすべてのステップでUTF-8が使用されていることを確認する必要があります。

入力CSVを作成するときは、UTF-8として、できればBOMなしで保存されていることを確認する必要があります。Windowsのメモ帳はBOMを追加するので、代わりにメモ帳++を試してください。これにより、エンコーディングをより細かく制御できます。

また、WindowsコンソールがデフォルトでUTF-8に準拠していないという問題もあります。WindowsコマンドラインのUnicode文字を参照してください-どのように?。STDOUTエンコーディングを使用してコードページを設定するか、chcp 65001変更しないでください。

コードに関しては、新しい行に関する最初のエラーは、CSVの末尾の新しい行が原因である可能性があります。chomp()後に追加while (<$INFILE>) {

アップデート:

ファイルを「アドレス指定」するには、ファイル名を正しいロケールでエンコードする必要があります。「Perlを使用してWindowsでUnicodeファイル名を作成する方法」および「Unicodeファイル名でファイルI / O APIを使用する一般的な方法は何ですか? 」を参照してください。。Western 1252 / Latinを使用しているとすると、これは、コピーコマンドが次のようになることを意味します。

copy(encode("cp1252", $old), encode("cp1252", $new))

また、openはファイル名もエンコードする必要があります。

open my $INFILE,  '<', encode("cp1252", $inputfile)

アップデート2:

DOSウィンドウで実行しているbinmode(STDOUT, ":utf8");ので、デフォルトのコードページを削除してそのままにしておきます。

于 2012-11-23T13:31:48.857 に答える