プロが教えるわが家の防犯対策術!

Win98SE で、ActivePerl 5.8.6 Build 811 を使っています。

以下は、ある条件に一致するファイル名を、指定パターンと連番のファイル名にリネームするスクリプトです。

print "Old pattern: ";
$opat = <STDIN>;
chop($opat);
print "New pattern: ";
$npat = <STDIN>;
chop($npat);
print "Starting #: ";
$i = <STDIN>;
chop($i);
@flist = glob("$opat");
foreach $old (@flist) {
  $new = sprintf("$npat", $i);
  print "Renaming $old --> $new\n";
  rename($old, $new);
  ++$i;
}
print "Done.\n";

このスクリプトは正しく動作しているのですが、これの先頭に、
  use encoding 'shiftjis';
を入れただけで、動かなくなってしまいます。
(rename にエラーチェックが入っていませんが、エラーチェックを追加すると、$old が No such file or directory となってしまいます。)

これは、なぜでしょうか?

ちなみに、perl -d で調べようにも、-d 付きでこのスクリプトを呼んだだけで Perl がクラッシュしてしまい、お手上げの状態です。

原因がおわかりの方、よろしくお願いします。

A 回答 (1件)

確かに、動かなくなるのはおかしいですね。


という訳で色々調べてみたのですが、use encoding…を入れると、chop の動作が変わってしまうことに原因があるようです。

つまり、通常は $opat = <STDIN>; を実行すると、$opat には「文字列+\r+\n」が入り、chop で \r\n を取ってくれるのですが、use encoding…が入っていると、$opat には「文字列+\r+\r+\n」が入るようです。

従って、chop を2回やらないと正しい文字列が得られないということになります。
(こういう時のために chomp がある筈なのですが、chomp を何度実行しても \r が取り切れませんでした。)

ということで、当面の回避策としては、chop を2回実行することで、何とかなりそうです。
(手元の環境で正しく動くことを確認しました。)
    • good
    • 0
この回答へのお礼

ご回答ありがとうございます。
確かに、chop の動作が変ですね。
そのため、$opat にゴミ(\r)が残り、$old にもそのまま \r が追加されていたため、rename で失敗した、ということのようですね。

chop を2回実行して、すべてうまく行くことを確認しました。
perl 5.8 で日本語サポートができたと喜んでいたのですが、完成度はまだまだ低いようですね。
どうもありがとうございました。

お礼日時:2005/01/03 13:25

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!