翻訳プロジェクトなどをみていて必要だったプログラム
#!/usr/bin/perl -w # argv[0] で指定したファイル(内容:ID,置き換え前文字列<LF>の羅列)を、 # argv[1]のファイル(内容:ID,置き換え後文字列<LF>の羅列)を使った IDをキーにして新たに書きだすプログラム # CRLFやカンマ、ダブルクオートのエスケープも行う。 # 文字エンコーディングはutf8に指定。 # 参考 http://codezine.jp/article/detail/1020 # 参考 http://hole.sugutsukaeru.jp/archives/13/2 # 参考 http://www.din.or.jp/~ohzaki/perl.htm#CSVwithCRLF my %csvdata = (); use strict 'refs'; use lib '..'; use utf8; use Encode; #カンマや改行を含むフィールドをクオートする関数 http://hole.sugutsukaeru.jp/archives/13/2 sub escape4txt{ my $str = shift; defined $str or return ''; return $str unless ($str =~ /[,"\r\n\t]/); $str =~ s/"/""/g; $str =~ s/\r\n/\n/g; return "\"$str\""; } binmode STDOUT, ":utf8"; open DATA, "<:utf8", $ARGV[1]; # 値に改行コードを含む CSV形式を扱う http://www.din.or.jp/~ohzaki/perl.htm#CSVwithCRLF while (my $line = <DATA>) { $line .= <DATA> while ($line =~ tr/"// % 2 and !eof(DATA)); $line =~ s/(?:\x0D\x0A|[\x0D\x0A])?$/,/; @values = map {/^"(.*)"$/s ? scalar($_ = $1, s/""/"/g, $_) : $_} ($line =~ /("[^"]*(?:""[^"]*)*"|[^,]*),/g); # hashへ登録 $csvdata{$values[0]} = $values[1]; } close DATA; # original fileの検索 open DATA, "<:utf8", $ARGV[0]; while (my $line = <DATA>) { $line .= <DATA> while ($line =~ tr/"// % 2 and !eof(DATA)); $line =~ s/(?:\x0D\x0A|[\x0D\x0A])?$/,/; @values = map {/^"(.*)"$/s ? scalar($_ = $1, s/""/"/g, $_) : $_} ($line =~ /("[^"]*(?:""[^"]*)*"|[^,]*),/g); # hashから登録 $newdata = $csvdata{$values[0]}; # print "ID: " . $values[0] . " | " . $values[1] . "=>" . $newdata . "\n"; print $values[0] . "," . &escape4txt($newdata) . "\n"; } close DATA;