PerlでCSVファイルやTSVファイルを列で分割する
csvファイルのある列を境にしてファイル分割が必要だったのでPerlで書いてみました。
今回やりたかった事としては、以下のhoge.csvからfoo.csvとbar.csvを生成するというものです。
データサンプル
hoge.csv(元ファイル)
NAME | AGE | ADDRESS | TEL | |
---|---|---|---|---|
Emacs君 | 25 | Tokyo | emacs@example.com | 03-XXXX-XXXX |
Vi君 | 25 | Sendai | vi@example.com | NULL |
秀丸君 | 20 | Osaka | hidemaru@example.com | 06-XXXX-XXXX |
↓ 分割後 ↓
bar.csv(分割されたファイル その2)
TEL | |
---|---|
emacs@example.com | 03-XXXX-XXXX |
vi@example.com | NULL |
hidemaru@example.com | 06-XXXX-XXXX |
Perlで実装
テキストファイルということでPerlで実装してみました。
処理の手順としては、
- ファイル(行)を読み込み
- 読み込んだデータ(行)をsplit(,)で配列に格納
- 配列の1〜3番目をjoin(,)して文字列として格納
- 配列の4〜5番目をjoin(,)して文字列として格納
- 格納した文字列をそれぞれのファイルに出力
といった感じになります。
ポイントとしては、添字の最大を表現する「$#row」。
例えば上記のhoge.csvだと、2行目のTELにNULLがセットされているのですが、
この状態で以下のようなコードで書くと警告が出てしまいました。(use warningsアリの場合)
指定した添字に対して配列の長さが足りないということで、警告が出てしまうようです。
なので、添字の最大については「$#row」のような形で動的に制御することで警告が出るのを防ぎました。
サンプルソースコード(ダメな例)
my $str_bar = join(',', @row[3..4]) . "\n";
サンプルソースコード(ダメな例)で発生する警告メッセージ(例)
Use of uninitialized value in join or string at split_csv.pl line 19, <IN_FILE> line 2.
上記の問題を解消した上で実装したコードが以下になります。
もう少しスマートな方法があるかもしれませんが、まずはこれでしばらく使ってみます。
・・・と思いましたが、下記のコードだと、
my $str_foo = join(',', @row[0..2]) . "\n";
で結局同じ問題が出てきてしまいますね。
うーん、あとで調べてみることにします。
サンプルソースコード(全部)
#!/usr/local/bin/perl # # split_csv.pl # use strict; use warnings; # FIle Open open( OUT_FOO, '> foo.csv') or die $!; open( OUT_BAR, '> bar.csv') or die $!; open( IN_FILE, 'hoge.csv') or die $!; while(<IN_FILE>){ s/\r\n|\n|\r//g; # 読み込んだ行をカンマ(,)で区切って配列(@row)へセット my @row = split/,/; # $#row -> 添字の最大(4) # ちなみに @row -> 要素数(5) my $str_foo = join(',', @row[0..2]) . "\n"; # データによっては警告が出ます。(Use of uninitialized value in join or string) my $str_bar = join(',', @row[3..$#row]) . "\n"; # それぞれのファイルへ出力 print OUT_FOO $str_foo; print OUT_BAR $str_bar; } # File Close close(OUT_FOO); close(OUT_BAR); close(IN_FILE);
今回参考にしたページ
SmartのWEB講座 > Perl講座 > 配列
http://www.rfs.jp/sb/perl/02/04.html
uninitialized value
http://www.dab.hi-ho.ne.jp/sasa/biboroku/perl/uninitialized_value.html