2011年09月11日

Text::CSV CSVの操作

CSV:Comma Separated Values : 区切り文字がコンマ
TSV:Tab Separated Values : 区切り文字がタブ

CSVよりTSVが便利そう。
CSVはセル内にコンマがあると扱いが難しい。
セル内にタブを使うことはない(?)から、TSVが楽かな。
ExcelからのコピペもTSVのようだし。

my @fields = split /,/, $line; # NG! セル内にコンマがあると使えない
my @fields = split /\t/, $line; # NG! 一般的にセル内にタブは使わない(?)



ただし、CSVもTSVも、一行ずつ処理する際に、改行を含むセルの扱いが難しい。
なので、PerlでCSVを使うときは、素直に「Text::CSV」を利用する。

PerlでCVSを使うには、このあたりかな。
Text::CSV (あればXS、なければPPを使う)
Text::CSV_PP (Pure Perl)
Text::CSV_XS (高速)
Text::CSV::Simple


ますは、インストール。

$ sudo cpan Text::CSV Text::CSV_XS Text::CSV::Simple



perldocから:

Embedded newlines
Unicode (UTF8)
FUNCTIONS
DIAGNOSTICS



わかりやすいサンプルコードがあるのでそのまま記載。

use Text::CSV;

my @rows;
open my $fh, "<:encoding(utf8)", "test.csv" or die "test.csv: $!";
while ( my $row = $csv->getline( $fh ) ) {
$row->[2] =~ m/pattern/ or next; # 3rd field should match
push @rows, $row;
}
$csv->eof or $csv->error_diag();
close $fh;

$csv->eol ("\r\n");

open $fh, ">:encoding(utf8)", "new.csv" or die "new.csv: $!";
$csv->print ($fh, $_) for @rows;
close $fh or die "new.csv: $!";





デフォルトでは、ASCIIしか扱えない、
セル内に改行など含む場合は、「binary=>1」を設定する。

改行の扱いで失敗する例:

my $csv = Text::CSV->new ({ binary => 1, eol => $/ });
while (<>) { # これだと、改行を含むセルが崩れる。
$csv->parse ($_);
my @fields = $csv->fields ();



良い例:

my $csv = Text::CSV->new ({ binary => 1, eol => $/ });
while (my $row = $csv->getline (*ARGV)) {
my @fields = @$row;


あるいは、perl5.6以上だと次の書き方がより安全。

my $csv = Text::CSV->new ({ binary => 1, eol => $/ });
open my $io, "<", $file or die "$file: $!";
while (my $row = $csv->getline ($io)) {
my @fields = @$row;



データ型を定義したいときは、「types」を使う。

$csv->types ([Text::CSV::IV (), # integer
Text::CSV::NV (), # numeric/float
Text::CSV::PV ()]); # string

$csv->types (undef); # リセット
$types = $csv->types (); # 現在の設定を取得

# IV Set field type to integer.
# NV Set field type to numeric/float.
# PV Set field type to string.





Posted by kanedayo at 23:56│Comments(0)
 
<ご注意>
書き込まれた内容は公開され、ブログの持ち主だけが削除できます。