古い記事
ランダムジャンプ
新しい記事
Excel のデータをスクリプトで処理するときは、「Unicode テキスト」で保存するとTSV形式になって扱いやすい。しかし、改行が入りのセルがあると簡単な行単位処理ができなくなり、いろいろと面倒。

「モジュール使え」って話ではあるけど、その場しのぎな簡単な対処方法がある。改行を含むセル(カラム)は必ずダブルクォートで囲まれているので、読込んだ行のダブルクォートを数え奇数だったら次の行も読んで足す、ってロジック。行頭からきちんとパーズしていかないとダメなケースもあるかと思うけど、まあそういうときはゴメン。別な対策を。

サンプルプログラムをのせておきますが、自己責任で。

■コード(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]
この記事に言及しているこのブログ内の記事