Excel のデータをスクリプトで処理するときは、「Unicode テキスト」で保存するとTSV形式になって扱いやすい。しかし、改行が入りのセルがあると簡単な行単位処理ができなくなり、いろいろと面倒。
「モジュール使え」って話ではあるけど、その場しのぎな簡単な対処方法がある。改行を含むセル(カラム)は必ずダブルクォートで囲まれているので、読込んだ行のダブルクォートを数え奇数だったら次の行も読んで足す、ってロジック。行頭からきちんとパーズしていかないとダメなケースもあるかと思うけど、まあそういうときはゴメン。別な対策を。
サンプルプログラムをのせておきますが、自己責任で。
■コード(tsv0a.pl):
■実行例:
テストファイル(tsv0a-test.txt):
実行結果:
なお、これにあわせて3年前に書いたCSVの処理も書き直した。というか、それのアップデートがそもそもの目的。
- PerlによるCSVの読み込みとCSVをTSVに変換するワンライナー[2012-03-09-1]
「モジュール使え」って話ではあるけど、その場しのぎな簡単な対処方法がある。改行を含むセル(カラム)は必ずダブルクォートで囲まれているので、読込んだ行のダブルクォートを数え奇数だったら次の行も読んで足す、ってロジック。行頭からきちんとパーズしていかないとダメなケースもあるかと思うけど、まあそういうときはゴメン。別な対策を。
サンプルプログラムをのせておきますが、自己責任で。
■コード(tsv0a.pl):
#!/usr/bin/env perl use strict; use warnings; my $line = ""; while (<>) { $line .= $_; my @dqm = $line =~ /\"/g; # double quote を数える next if @dqm % 2; # 奇数なら次の行を末尾に足す { # 何かの処理 chomp $line; print "\nINPUT: [$line]\n"; ### Case1: カラム中の改行を削除し1行で出力 $line =~ s/\n//g; # print "$line\n"; ### Case2: カラム単位で処理 my @c = map {s/^"(.*)"$/$1/gs; $_} split(/\t/, $line); # ↑タブで分割し両端の「""」を削除 print "RESULT: ".join(",", map {qq("$_")} @c)."\n"; } $line = ""; # 処理後は空にする }
■実行例:
テストファイル(tsv0a-test.txt):
this foo that "foo+ bar" 100 "4/ 25" "31/ 365" hoge "hoge" "hoge" "hoge" hoge "hoge" "hoge/ hoge" hoge
実行結果:
% ./tsv0a.pl tsv0a-test.txt INPUT: [this foo] RESULT: "this","foo" INPUT: [that "foo+ bar" 100] RESULT: "that","foo+bar","100" INPUT: ["4/ 25" "31/ 365"] RESULT: "4/25","31/365" INPUT: [hoge "hoge" "hoge"] RESULT: "hoge","hoge","hoge" INPUT: ["hoge" hoge] RESULT: "hoge","hoge" INPUT: ["hoge" "hoge/ hoge" hoge] RESULT: "hoge","hoge/hoge","hoge"
なお、これにあわせて3年前に書いたCSVの処理も書き直した。というか、それのアップデートがそもそもの目的。
- PerlによるCSVの読み込みとCSVをTSVに変換するワンライナー[2012-03-09-1]
この記事に言及しているこのブログ内の記事