集計データを通常のテーブルに変換する

集計データを通常のテーブルに直す為のプログラムを考える。

まず元データを用意する。

$ echo -e "title,label1,label2,label3\nA,1,2,3\nB,4,5,6\nC,7,8,9\nD,10,11,12"
title,label1,label2,label3
A,1,2,3
B,4,5,6
C,7,8,9
D,10,11,12

ファイル書けって説があるがそれはご愛敬。(折角のecho -eは活用しないと)
で、紆余曲折したあげく出来たスクリプト(?)が以下

ruby -ne 'l="";$.==1?c=$_.split(/,|\n/):$_.split(/,|\n/).each_with_index{|v,i|i==0?l=v:puts([c[i],l,v].join(","))}'

変数を一つ使ってしまった。

$ echo -e "title,label1,label2,label3\nA,1,2,3\nB,4,5,6\nC,7,8,9\nD,10,11,12" | ruby -ne 'l="";$.==1?c=$_.split(/,|\n/):$_.split(/,|\n/).each_with_index{|v,i|i==0?l=v:puts([c[i],l,v].join(","))}'
label1,A,1
label2,A,2
label3,A,3
label1,B,4
label2,B,5
label3,B,6
label1,C,7
label2,C,8
label3,C,9
label1,D,10
label2,D,11
label3,D,12


以下は前のバージョン

ruby -e 'c=gets.chop.split(/,/);readlines.each{|i|l=i.split(/,/);(1..l.size-1).each{|j|puts "#{c[j]},#{l[0]},#{l[j]}"}}'

以下はデータの大きさに合わせて動作する例

$ echo -e "title,label1,label2,label3\nA,1,2,3\nB,4,5,6\nC,7,8,9\nD,10,11,12" | ruby -e 'c=gets.chop.split(/,/);readlines.each{|i|l=i.split(/,/);(1..l.size-1).each{|j|puts "#{c[j]},#{l[0]},#{l[j]}"}}'
label1,A,1
label2,A,2
label3,A,3
label1,B,4
label2,B,5
label3,B,6
label1,C,7
label2,C,8
label3,C,9
label1,D,10
label2,D,11
label3,D,12
$ echo -e "title,label1,label2\nA,1,2\nB,4,5\nC,7,8\nD,10,11" | ruby -e 'c=gets.chop.split(/,/);readlines.each{|i|l=i.split(/,/);(1..l.size-1).each{|j|puts "#{c[j]},#{l[0]},#{l[j]}"}}'
label1,A,1
label2,A,2
label1,B,4
label2,B,5
label1,C,7
label2,C,8
label1,D,10
label2,D,11

こうやると最終フィールドもレコードに追加するようになる。

$ echo -e "title,label1,label2\nA,1,2\nB,4,5\nC,7,8\nD,10,11" | ruby -e 'c=gets.chop.split(/,/);readlines.each{|i|l=i.split(/,/);(1..l.size-2).each{|j|puts "#{c[j]},#{l[0]},#{l[j]},#{l[l.size-1]}"}}'
label1,A,1,2
label1,B,4,5
label1,C,7,8
label1,D,10,11

まあ、その辺に転がっているhtmlの集計テーブルデータをテーブルに直した痕跡。(備忘用)

cat a.txt| ruby -e 'print STDIN.read.gsub(/<[^>]+>/,"").split(/\n/).map{|i|i.strip.gsub(" ","")}.select{|i|i!=""}.join("\n")' | tail -n +14 | head -220 | perl -pe '$.%10&&s/\n/,/' | ruby -e 'c=gets.chop.split(/,/);readlines.each{|i|l=i.split(/,/);(1..l.size-2).each{|j|print"#{j},#{c[j]},#{l[0]},#{l[j]},#{l[l.size-1]}"}}'

SQLに集計テーブルを元のテーブルに戻す作業(縦展開?)が見あたらないように結構面倒な作業なんだな。