Edited at

shellでcross集計(個人的メモ)

More than 3 years have passed since last update.


Data

https://github.com/mwaskom/seaborn-data/blob/master/tips.csv


参考

http://www.slideshare.net/iktakahiro/bashawk

http://kunst1080.hatenablog.com/entry/2013/06/01/160617

http://kunst1080.hatenablog.com/entry/2013/06/02/234025


script

# 先頭行にデータheaderがある場合飛ばして、タブ区切りで出力

awk 'BEGIN{OFS="\t"}NR>1{print $5,$6}' < tips.csv > tmp_data.txt
cut -f1 tmp_data.txt|sort -u > rowname.txt
cut -f2 tmp_data.txt|sort -u > tmp_header.txt
# awkをはさんで最後尾に改行コードを付加しておく
tr '\n' '\t' < tmp_header.txt | awk '{print}' > header.txt
awk {'print > "split_"$2'} tmp_data.txt
# セルごとの集計を行う(縦持ち)
for file in `< tmp_header.txt`;
do
# parallelize
(
# countの場合(sumの場合は+1の部分を変更する)
awk '{a[$1]+=1;}END{for(i in a)print i","a[i];}' split_${file} | sort > sort_${file}
# joinして行基準で0埋め
# rowname.txtの1列目とsort_hogeファイルの1列目でjoin
# aオプションはsort_hogeに行が欠損してmatchしなかった場合も空で含める
join -t',' -1 1 -2 1 -a 1 rowname.txt sort_${file} | awk -F, '{print $2}' | sed 's/^$/0/g' > split_sum_${file}
) &
done
wait

cp header.txt sum_result.tsv
paste rowname.txt split_sum_* >> sum_result.tsv