UNIXコマンドの結果には必ず改行文字がくっついている

例えば、このようにして読み込むファイル名を使って出力ファイル名をつくるケースがあるとします。

my @files = `ls *.txt`;
my ($r, $w) = ();

for my $r_file (@files) {
  my $w_file = "ex_$r_file";
  open $r, $r_file;
  open $w, $w_file;
  print $w "#".$_ for <$r>;
  close $r;
  close $w;
}

出力ファイルをunlinkで初期化しようとしようとするとunlinkに失敗し初期化はされません。or dieを付けていれば、ここでdieします。

for my $r_file (@files) {
  my $w_file = "ex_$r_file";
  unlink $w_file or die if -e $w_file;  # unlinkに失敗する
  open $r, $r_file;
  open $w, $w_file;
  print $w "#".$_ for <$r>;
  close $r;
  close $w;
}

これはlsでとってきたファイル名に改行文字がついているためです。

for my $r_file (@files) {
  chomp $r_file;                        # 改行文字を除去
  my $w_file = "ex_$r_file";
  unlink $w_file or die if -e $w_file;  # 正常に処理
  open $r, $r_file;
  open $w, $w_file;
  print $w "#".$_ for <$r>;
  close $r;
  close $w;
}

open/closeは改行文字がついたままでもエラーにならないので、ついchompするのを忘れてしまいました。

PerlUNIXコマンドを直接たたくときは常に改行文字を意識していないとダメですね。