ルモーリン
ホーム 更新 Perl Sample サービス 雑談 鉄ゲタ Linux リンク 連絡先

Perlサンプル4 ファイルの読み込み

2019-08-24

引数に指定したファイルから読み込んで1行ずつ表示します。

#!/usr/bin/env perl

use v5.26;
use utf8;
use strict;
use warnings;

use Encode::Argv;
use Encode::Locale;

use open IO => ":utf8";
binmode STDIN, ":encoding(console_in)";
binmode STDOUT, ":encoding(console_out)";
binmode STDERR, ":encoding(console_out)";

$| = 1;

1 == @ARGV or die "ファイルが指定されていません\n";
say "ファイル名:$ARGV[0]";
if (open my $fh, "<:utf8:crlf", Encode::encode locale_fs => $ARGV[0]) {
	my $line = 0;
	while(<$fh>) {
		chomp;
		$line++;
		say "行 $line, '$_'";
	}
	close $fh;
} else {
	die "ファイル「$ARGV[0]」を開けません:$!\n";
}
ファイル名:perlsample_004.txt
行 1, 'たこルカは俺の嫁'
行 2, 'ルカ姐さんも俺の嫁'

binmode STDERR, ":encoding(console_out)"

標準エラー出力の文字コードをSTDOUTと同じくconsole_outに設定します。

or

orの左が偽の場合にorの右を評価します。 このサンプルでは@ARGVの要素が1でない場合にdieを呼びます。 or演算子の優先順位がとても低いので「orの左側全部」と「orの右側全部」に分けて読めます。
「論理和と排他論理和」
perlop - Perl の演算子と優先順位 - perldoc.jp

die

標準エラー出力にメッセージを出して終了します。 末尾に改行を入れて、Perlの追加メッセージを抑止します。
Perlの組み込み関数 die の翻訳 - perldoc.jp

"<:utf8:crlf"

<でファイルの読み出し、:utf8でファイルの文字コード、:crlfで改行コードは0x0d、0x0aを指定します。 書き込みは>、既存のデータを残して末尾に追加は>>です。 :crlfは守備範囲が広く、改行コードが0xaのファイルもきちんと読み出せますから読み出しに:crlfをお勧めします。 もしプログラムの冒頭でuse open IO => ":utf8:crlf"とした場合は、書き込みのファイルの改行コードが0xd、0xaになります。
Perlの組み込み関数 open の翻訳 - perldoc.jp

Encode::encode locale_fs => $ARGV[0]

開くファイルのファイル名の文字コードをファイルシステムに合わせた文字コードに変換します。 locale_fsはファイル名の文字コードです。 Windowsはcp932(シフトJISの親戚)、Linuxはutf8です。
Encode::Locale - Determine the locale encoding - metacpan.org

while(<$fh>)

1行ずつ読み出してループします。 ループを抜けても$_は戻らないので注意。 この書き方で2重ループ(例えば外側のループで読み込んだ行に書かれているファイルを開き、内側のループでその行を読む)にすると$_の更新も2重です。
「I/O 演算子」
「通常は、返された値を変数に代入しなければなりませんが、自動的に 代入される場合が 1 つだけあります。 この入力シンボルが、while 文(for(;;) の形になっていたとしても)の条件式中に 単独で現れた場合だけは、その値が自動的にグローバル変数 $_ に代入されます」
perlop - Perl の演算子と優先順位 - perldoc.jp