camel

このことに異論はないのだけど、

CodeZine:PerlによるCSVファイルの高速集計(CSV, 入門, Perl)
特によく利用されるテキストファイルとして、CSV形式が挙げられます。CSVを集計したい場合、Excelに読み込ませて集計関数やマクロを駆使しているという人も多いかと思いますが、Perlを利用することで、高度な集計作業を簡単かつ高速にできます。

これはちょっと問題。

my @d = split(/,/, $_);

実はCSVというのは以外と扱いにくいフォーマットで、例えば"I, Robot","Robots and Empire"とあったら、I, RobotRobots and Empireと取り出すフィールドは二つでなければならないのだけど、記事の例だと"I Robot","Robots and Empire"とフィールドが3つ出来てしまう上に、引用符が入ったままになってしまう。

こういう「簡単そうにみえて実はややこしいデータ構造」を扱う場合、のび太がどらえもんにお願いするように、CPANにお願いするのが吉。この場合、答えはText::CSV_XSまたはText::CSVということになる。

たとえば、CSVをTSV(tab seperated value)に変換するscriptは、以下のようになる。

#!/usr/local/bin/perl
use strict;
use warnings;
use Text::CSV_XS; # or Text::CSV_XS
my $tc = Text::CSV_XS->new;
while(<>){
    next unless $tc->parse($_);
    my @fields = $tc->fields;
    print join("\t", @fields), "\n";
}
__END__

どちらがインストールされているかわからない場合は、こういう手もある。

my $tc = do{
    eval { require Text::CSV_XS };
    unless ($@){
        Text::CSV_XS->new;
    }else{
        eval { require Text::CSV };
        die "Neither Text::CSV_XS nor Text::CSV is available" if $@;
        Text::CSV->new;
    }
};

「素」Perlでこういうデータを扱う場合は、むしろTSVの方がよいだろう。このあたりは、以前「404 Blog Not Found:TSV vs CSV」のでそちらも参照のこと。さらに詳しく知りたい人は、Cookbookを参照のこと。


Dan the Man with Too Many Data Formats to Juggle