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