gikoha’s blog

個人的メモがわり

CSVのIDを使ったハッシュ

翻訳プロジェクトなどをみていて必要だったプログラム

#!/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;