Memoize2

Perl Shift_JIS(cp932) の CSV を JSON に変換する

cp932CSV2JSON.pl


#! /usr/bin/perl -w
# Windows-31j(cp932) の CSV を JSON 化する。1つの CSV row が1つの JSON obj になる仕様
use utf8; # use utf8 しないと JSON モジュールが正常に動作しないことがあるらしい。
use Text::CSV_XS;
use JSON::XS;

my $file = shift or die "no csv."; # コマンドライン引数から1ファイル読み込む
my $delimiter = ","; # field separator, タブ区切りのファイルもあったりするよね
my $csv = Text::CSV_XS->new({binary => 1, sep_char => $delimiter, eol => "\r\n"});
#   binary => 1 しないとマルチバイト文字列は処理できません
#   eol => "\r\n" 読み込み対象ファイルの改行スタイルにあわせる必要あり

# PerlIOレイヤーを使って読み込むCSVのエンコーディングをPerlに指示します
open my $fh, "<:encoding(cp932)", $file or die "$file: $!";

# 対象ファイルの1行目がヘッダー行である前提で
my $is_header = 1;
# 2行目以降のデータ行をハッシュ化するためにヘッダーを保存しておく変数
my $headers;

# ハッシュをJSONオブジェクトとして書き出すためのオブジェクトを作っておく
my $json = JSON::XS->new;
$json = $json->utf8(1); # このパラメータ指定によって utf8 文字列になった状態で print できるよ
$json = $json->pretty(0); # -> Python json で言うところの indent=None。改行なしでコンパクトな出力形式

while (my $row = $csv->getline($fh)) {
    if ($is_header) {
        $is_header = 0;
        $headers = $row;
        next;
    }
    
    # 2つの配列を ZIP するテクニック
    my %hash;
    @hash{@$headers} = map { s/\015//gr } @$row;
    # 補足: \015 == \r
    #   格データ要素の中に含まれているCRを削除している

    print $json->encode(\%hash), "\n";
}

close $fh;

使用例:


$ perl cp932CSV2JSON.pl win_sjis.csv > utf8.json

関連記事:

iconv Windows-31j(CP932)(CRLF)とUTF-8(LF)間の変換 - memoize2

参考:

CSV の取り扱い - perl-users.jp
CPAN - Text::CSV_XS
How can I assign two arrays to a hash in Perl? - stackoverflow
CPAN - JSON
CPAN - JSON::XS

 

Last modified: 2016-12-25

Page Top

Index

Bw

Author: 中村 心 Shin Nakamura, Email: sn(at)i.basicwerk.com


© Shin Nakamura/BasicWerk 2008 - 2017