
Perlで、引数にファイル名が与えられた時にファイルをunicodeファイルとして開く方法と、引数のファイル名そのものが漢字(日本語)の場合のperlの書き方について。
Macなので、TerminalはUTF8で動いているものとします。
while(<>)
の場合
陰で自動的にファイルがopenされるので、それに対してbinmode ":utf8"を指定しなければなりません。
これはuse open ":utf8";
です。
これで全openは自動的にUTF-8を指定したことになります。従って、陰でopenされる時もUTF-8のファイル内容として読み書きしてくれます。
@ARGVの中のファイル名
漢字のファイル名が引数になっていた場合、print $ARGV[0];
すると文字化けします。渡されたファイル名の文字列がバイナリー扱いになっていて、perlの内部表現(use utf8;
)になっていないためです。そこでdecodeを使って内部表現へ変換してやります。
decode("utf8", $ARGV[0]);
は、第2引数はUTF-8の文字列なので内部表現に変換しろという意味。encode()
じゃないのか?と思ってしまいますが逆です。
opendir()
/ readdir()
opendirに渡すファイル名の文字列は生のままの$ARGV[0]でも、decode("utf8", $ARGV[0])
でも正常にopendirできるようです。
readdirしたファイル名もバイナリー状態なのでそのままprintすると文字化けします。decode()
してから使います。ただ上述のようにopendirやopenの引数として使うだけなら、生のままでも使えます。
例
use strict;
use warnings;
use Encode qw(decode);
#use Data::Dumper;
use utf8;
binmode STDIN, ":utf8";;
binmode STDOUT, ":utf8";
binmode STDERR, ":utf8";
use open ":utf8";
#
# example 1
#
# 'use open ":utf8";'がないと<>で自動的にopenされる
# ファイルをreadした時の文字コードがUTF-8にならない
#
while(<>) {
print;
}
#
# example 2
#
# @ARGVの中身の文字コードが定まってない(バイナリー扱い)ので
# decode()を使って、UTF-8だと教えてやる。
# するとprintや文字列マッチで正しく扱えるようになる。
#
# open()やopendir()はdecode()してない文字列でも正常に動くようだ
# ファイル名を単にopen()/opendir()にしか使わないなら
# decode()を通さなくても一応問題なく使える
#
# readdir()で返ってくるファイル名も
# バイナリーのままなのでdecode()必要
#
# ここのopen()も'use open ":utf8";'によって
# UTF-8をread/writeするようになっているので
# <$FH>で読んだ行が文字化けせずにprintされる
#
foreach my $file (@ARGV) {
$file = decode("utf8", $file);
print STDERR "***$file\n";
if (-d $file) { # directoryならファイル一覧を出してみる
opendir my $DH, $file or die "$file: $!\n";
while(readdir($DH)) {
print decode("utf8", $_);
#print "$_\n"; # これだと漢字のファイル名が文字化けする
}
closedir $DH;
} else { # ファイルなら中身を出力してみる
open my $FH, "<", $file or die "$file: $!\n";
while(<$FH>) {
print;
}
close $FH;
}
}
参考にしたサイト
- 文字コードの指定 - ファイル操作 - Perl入門 | PerlPlus
- Perl 5.8.x Unicode関連 | ++ KUROITA ++ CGI and Studying
- Encode - 日本語などのマルチバイト文字列を適切に処理する / Perlモジュール徹底解説 - サンプルコードによるPerl入門
- Perl: 文字コードとutf8フラグについて - @bayashi Wiki
- Perlによる日本語コード変換のメモ(第二版) | hikoboshi.home
0 件のコメント:
コメントを投稿