PerlでCSVの読み書きを学ぶための自作ドリル
CSVを扱うと同時に、パッケージモジュールの扱いにも慣れさせるための問題と解答例。
モジュールはText::CSV_XSを使用。
問題
CSV書き出しスクリプト
name, email, addressを入力して、CSVでファイルに書き出す。(項目名はプロンプトとして表示する。)
実行結果
$ perl output_csv.pl name : Taro Yamada(改行) email : taro.yamada@xxx.com(改行) address : tokyo(改行) name : Jiro Tanaka(改行) email : jiro.tanaka@xxx.com(改行) address : osaka(改行) name : Saburo Abe(改行) email : saburo.abe@xxx.com(改行) address : nagoya(改行) name : (Ctrl+Dで終了) $
書き出し結果ファイル(output_xxxxxxxxxx.csv)
name,email,address "Taro Yamada",taro.yamada@xxx.com,tokyo "Jiro Tanaka",jiro.tanaka@xxx.com,osaka "Saburo Abe",saburo.abe@xxx.com,nagoya
CSV読み込みスクリプト
CSVファイルを読み込み、マップ形式で画面に表示する。
読み込みファイル(output_xxxxxxxxxx.csv)
name,email,address "Taro Yamada",taro.yamada@xxx.com,tokyo "Jiro Tanaka",jiro.tanaka@xxx.com,osaka "Saburo Abe",saburo.abe@xxx.com,nagoya
実行結果
$ perl input_csv.pl output_xxxxxxxxxx.csv (1) name : Taro Yamada email : taro.yamada@xxx.com address : tokyo (2) name : Jiro Tanaka email : jiro.tanaka@xxx.com address : osaka (3) name : Saburo Abe email : saburo.abe@xxx.com address : nagoya $
解答例
CSV書き出しスクリプト
use strict; use warnings; use utf8; use Text::CSV_XS; binmode STDIN, ':utf8'; binmode STDOUT, ':utf8'; binmode STDERR, ':utf8'; # CSV Parser my $csv = Text::CSV_XS->new({binary=>1}); # 書き出しファイル名 my $csvout_name = $ARGV[0] || 'output_' . time . '.csv'; # File Check if (-e $csvout_name) { print STDERR "$csvout_name already exists.\n"; exit 1; } # Input Data Table my @labels = ('name', 'email', 'address'); my @table = ([]); # Input Data my $finish = 0; while ($finish == 0) { print $labels[scalar(@{$table[-1]})] . ' : '; if (my $param = <STDIN>) { $param =~ s/[\r\n]//go; if ($param ne '') { push @{$table[-1]}, $param; if (@{$table[-1]} >= @labels) { push @table, []; } } } else { $finish = 1; if (@{$table[-1]} > 0) { for (my $cnt = @{$table[-1]}; $cnt < @labels; $cnt++) { push @{$table[-1]}, ''; } } else { pop @table; } } } print "\n"; unshift @table, [@labels]; # File Double-check if (-e $csvout_name) { print STDERR "$csvout_name already exists.\n"; exit 1; } # CSV Output open my $csvout, '>:utf8', $csvout_name; foreach my $row (@table) { $csv->combine(@$row); print $csvout $csv->string . "\n"; } close $csvout; exit 0;
CSV読み込みスクリプト
use strict; use warnings; use utf8; use Text::CSV_XS; binmode STDIN, ':utf8'; binmode STDOUT, ':utf8'; binmode STDERR, ':utf8'; # CSV Parser my $csv = Text::CSV_XS->new({binary=>1}); # Input Check if (@ARGV != 1) { print STDERR "Please input CSV file name.\n"; exit 1; } # 読み込みファイル名 my $csvin_name = $ARGV[0]; # File Check unless (-f $csvin_name) { print STDERR "$csvin_name is not found.\n"; exit 1; } # Input CSV open my $csvin, '<:utf8', $csvin_name; my @table = (); while (my $line = $csv->getline($csvin)) { push @table, $line; } close $csvin; # Output CSV Data my @labels = (@table > 1) ? @{(shift @table)} : (); for (my $rowcnt = 0; $rowcnt < @table; $rowcnt++) { print '(' . ($rowcnt + 1) . ')' . "\n"; for (my $colcnt = 0; $colcnt < @{$table[$rowcnt]}; $colcnt++) { print "\t"; if (@labels > 0) { print $labels[$colcnt] . ' : '; } print $table[$rowcnt][$colcnt] . "\n"; } } exit 0;