5

UTF-16 でエンコードされたテキストファイルがあります。各行には、タブで区切られた多数の列が含まれています。気にする方のために説明すると、ファイルは iTunes からのプレイリスト TXT エクスポートです。列 27 にはファイル名が含まれています。

次のようなコードを使用して、LinuxでPerl 5.8.8を使用して読んでいます。

binmode STDIN, ":encoding(UTF-16)";
while(<>)
{
    chomp;
    my @cols = split /\t/, $_;
    my $filename = $cols[26];   # Column #27 contains the filename
    print "File exists!" if (-e "$filename");
}

(注: このコード スニペットは短縮しました。実際のコードでは、iTunes で使用される Windows の絶対ファイル名を Linux ボックスで有効なファイル名に変換するためにいくつかの置換を行います)

ファイルは存在しますが、(-e) ファイル テストは true を返しません。文字列が UTF-16 であることと関係があると思いますが、何が問題なのかわかりません。実際のファイル名は ASCII 文字のみを使用します。$filename 変数を出力すると、ファイル名が正しく出力されます。

Perlのファイル名はUTF16にできますか? このコード スニペットを機能させる方法はありますか?

4

3 に答える 3

5

UTF-16 テキストは、:encoding レイヤーによって処理されます。に入るまでに、$_それが UTF-16 であったことを伝える方法はありません。それはあなたの問題ではないと思います。

私の推測では、ファイル名に空白が含まれている (印刷しようとしたときに気付かなかった) か、自分がいると思っているディレクトリにいない可能性があります。

試す

if (-e $filename) { print "File exists!" } 
else { print "File <$filename> not found" }

ファイル名を注意深く確認してください。use Cwd;現在のディレクトリを印刷することもできます。

于 2009-08-22T20:47:30.723 に答える
4

私は解決策を見つけました:

列 27 は最後の列であり、ファイルは 0d0a (\r\n) 行末でエンコードされます。chomp は 0a (\n) のみを削除していました。なぜ以前にこれを見なかったのかわかりませんが、UTF16 とは何の関係もありません。

追加:

s/\r$//;

chomp が問題を修正した後。

助けてくれてありがとう - うさぎの道に送ってすみません。

于 2009-08-22T20:52:49.403 に答える
2

あなたが言うように、実際のファイル名がASCII文字のみを使用している場合、

$filename =~ s/\0//g;

仕事?とにかく、xxd次にこのようなことに遭遇したときに役立つはずです

[sinan@archardy ~]$ xxd /mnt/c/Documents\ and\ Settings/sinan/Desktop/test.txt
0000000: fffe 2f00 6800 6f00 6d00 6500 2f00 7300 ../.home/.s.
0000010: 6900 6e00 6100 6e00 2f00 7400 6500 7300 inan/.tes
0000020: 7400 6d00 6500 2e00 7400 7800 7400 0d00 tme..txt..
0000030: 0a00 ..

テスト ファイルを作成して Linux を再起動するのにかかった時間で、問題が解決したようです。しかたがない。

于 2009-08-22T20:17:06.917 に答える