文字列から最後の改行を削除する
chomp
は、通常は文字列の最後の改行文字を取り除きます。
そして、引数から削除された文字数を返します。
もし引数が指定されなければ、$_ の値を処理します。
my $str = "Hello\n";
my $num = chomp $str;
print $num; # 1
print $str; # "Hello" (\n が取り除かれている)
chomp
は、正確には末尾の改行を削除するというよりかは、
特殊変数 $/ にセットされた値を削除します。
この変数には Linux においても Windows においても LF (0x0A) がセットされています。
結果的に末尾の改行が削除されることになります。
当然、特殊変数 $/ に別の文字を設定すれば、末尾の改行は削除されません。
chomp
には連想配列を与えて、すべての値の末尾の改行を取り除くことができます。
my %data = (
greeting1 => "Hello\n",
greeting2 => "Hi\n",
greeting3 => "Howdy\n"
);
my $num = chomp %data;
print $num; # 3
print $data{greeting1}; # "Hello" (\n が取り除かれている)
この場合、chomp
は取り除いた改行の数を返します。上記のサンプルコードでは 3 を返します。
chomp
には配列を与えることもできます。この場合、配列のすべての要素の末尾の改行を取り除きます。
my @list = ( "Hello\n", "Hi\n", "Howdy\n" );
my $num = chomp @list;
print $num; # 3
print $list[0]; # "Hello" (\n が取り除かれている)
さらに、chomp
にはリストを与えることもできます。
しかし、リストを与える場合は chomp
に括弧が必要ですので注意してください。
my $str1 = "Hello\n";
my $str2 = "Hi\n";
my $str3 = "Howdy\n";
my $num = chomp( $str1, $str2, $str3 );
print $num; # 3
print $str1; # "Hello" (\n が取り除かれている)
chomp
の利用において 1 点注意が必要です。
それは行末が Windows の改行コード CRLF (0x0D0A) の場合です。
改行コードが CRLF のテキストファイルを Linux や MacOS で読み込むと問題が生じます。
$/ には LF (0x0A) がセットされているということは、
chomp
を使っても CR (0x0D) が残ってしまいます。
従って、テキストに CRLF が含まれるテキストを Linux や MacOS で扱う場合、
chomp
を使った後に、CR (0x0D) も削除しないといけません。
open my $fh, '<', './sample.txt';
while ( my $line = <$fh> ) {
chomp $line; # ここで末尾の LF が削除される
$line =~ s/\r$//; # ここで末尾の CR が削除される
...
}
close $fh;
改行コードが CRLF のテキストファイルを読み込んでも、Windows の場合は
chomp
だけで期待通りに末尾の改行は取り除かれます。
CR が残ってしまう現象は発生しません。
$/ に LF (0x0A) がセットされているにもかかわらず、CR (0xD0) まで
chomp
で削除されてしまうというのは不思議に感じないでしょうか。
実は、Windows の場合、
ファイルをテキストモードで読み込むと、自動的に CRLF が LF に変換されます。
そして、スクリプト内部では \n
も $/
も LF (0x0A) です。
加えて、テキストモードでテキストをファイルに書き込む際にも、自動的に LF が CRLF に変換されます。
そのため、Windows で実行される Perl スクリプト側では、テキストファイルの改行が CRLF
であることを意識する必要はありません。