chomp

文字列から最後の改行を削除する

構文

解説

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 であることを意識する必要はありません。