Home > プログラミング > 最萌トーナメントの集計スクリプト

最萌トーナメントの集計スクリプト

AWK の勉強のためとの建前で 第2回東方最萌トーナメント の集計スクリプトを書いてみた.スレッドの番号を入れると wget でページを落としてきて解析して gnuplot でグラフを描いてくれる.あほだ...

ファイルを置いといてみる.

ついでなのでコードでも書いておいてみよう.

メインは cnt.sh.

gnuplot があればグラフもはく.

(ソース中のコマンドは pgnuplot になってる)

cnt.sh:

DATAFILE=\"data.dat\" RESULTFILE=\"result.txt\" CH1DAT=\"ch1.dat\" CH2DAT=\"ch2.dat\" CH1DATTIME=\"ch1time.dat\" CH2DATTIME=\"ch2time.dat\" GPLFILE=\"plot.gpl\" BBSADDR=\"http://jbbs.livedoor.jp/bbs/read.cgi/game/20311/\" GRAPHMAXY=800
CH1=$1 CH2=$2 DAT=$3 shift shift shift
echo -n \"\" > $DATAFILE
cnt=$1 shift while [ $cnt -gt 0 ] do echo $1 echo $cnt mv $DATAFILE tmp.dat cat tmp.dat $1 >> $DATAFILE shift cnt=`expr $cnt - 1` done
for i in $* do rm $i wget $BBSADDR$i mv $DATAFILE tmp.dat cat tmp.dat $i >> $DATAFILE done
./count.sh $CH1 $CH2 $DAT $DATAFILE > $RESULTFILE
cat $RESULTFILE | nkf --euc | awk -f split.awk -v TARGET=\"1st\" | nkf --sjis > $CH1DAT cat $RESULTFILE | nkf --euc | awk -f split.awk -v TARGET=\"2nd\" | nkf --sjis > $CH2DAT cat $RESULTFILE | nkf --euc | awk -f split.awk -v TARGET=\"acc\" | nkf --sjis
cat $RESULTFILE | nkf --euc | awk -f split.awk -v TARGET=\"1stTime\" | nkf --sjis > $CH1DATTIME cat $RESULTFILE | nkf --euc | awk -f split.awk -v TARGET=\"2ndTime\" | nkf --sjis > $CH2DATTIME
echo -n \"\" > $GPLFILE echo \"set terminal postscript eps color solid lw 1\" >> $GPLFILE echo \"set output \\"graph-$CH1-$CH2.eps\\"\" >> $GPLFILE echo \"set key left\" >> $GPLFILE echo \"set boxwidth 0.3 relative\" >> $GPLFILE echo \"set xdata time\" >> $GPLFILE echo \"set timefmt \\"%H:%M\\"\" >> $GPLFILE echo \"set format x \\"%H:%M\\"\" >> $GPLFILE echo \"set xrange [\\"00:00\\":\\"23:10\\"]\" >> $GPLFILE echo \"set xtics \\"00:00\\", 10800, \\"24:00\\"\" >> $GPLFILE echo \"set yrange [0:$GRAPHMAXY]\" >> $GPLFILE echo \"set multiplot\" >> $GPLFILE echo \"set style data lines\" >> $GPLFILE echo \"set style line 1 lw 3\" >> $GPLFILE echo \"set style line 3 lw 3\" >> $GPLFILE echo \"plot \\"ch1.dat\\" using 1:2 ls 1 title \\"$CH1\\", \\"ch2.dat\\" using 1:2 ls 3 title \\"$CH2\\"\" >> $GPLFILE echo \"set style data boxes\" >> $GPLFILE echo \"plot \\"ch1time.dat\\" using ((\$1*60+20)*60):2 ls 1 title \\"\\", \\"ch2time.dat\\" using ((\$1*60+40)*60):2 ls 3 title \\"\\"\" >> $GPLFILE echo \"unset multiplot\" >> $GPLFILE echo \"set output\" >> $GPLFILE
pgnuplot $GPLFILE

split.awk:

BEGIN {
	FLAG=0
	STARTPat=\"Start of \"TARGET
	ENDPat=\"End of \"TARGET
}
//{
	if($0 == ENDPat){
		FLAG = 0
	}
	if(FLAG) print
	if($0 == STARTPat){
		FLAG = 1
	}
}

count.awk:

BEGIN {
RS = \"<dt>\" # 環境から取得 ch1str=ENVIRONCH1STR # キャラ名1 ch2str=ENVIRONCH2STR # キャラ名2 ch1all=ENVIRONCH1ALL # キャラ名リスト1 ch2all=ENVIRONCH2ALL # キャラ名リスト2 date=ENVIRONDATE # 日付 split(ch1all,ch1,\";\") # 配列に直す split(ch2all,ch2,\";\") print \"Date: \" date print \"Ch1: \" ch1str print \"Ch1All: \" ch1all print \"Ch2: \" ch2str print \"Ch2All: \" ch2all } //{ # 日付チェック if($0 !~ date) next # レス番号 pos=match($0, /<a [^>]*>[0-9]+<\/a>/) if(!pos) next resnum = substr($0, pos, RLENGTH) gsub(/<a [^>]*>/, \"\", resnum) gsub(/<\/a>/, \"\", resnum) if((resnum+0) < 5 || (resnum+0) > 950) next # 同一レス内二重投稿チェック str=$0 numofent=gsub(/<<([^&]*)>>/, \"\", str) if(numofent == 0 || numofent>1) next # code チェック pos=match($0, /\[\[([^\]]*)\]\]/) if(!pos) next str = substr($0, pos, RLENGTH) if(codes[str]) { codes[str]++;
} else { codes[str]++; } # 取り出し pos=match($0, /<<([^&]*)>>/) if(!pos) next str = substr($0, pos, RLENGTH) gsub(/<|>/, \"\", str)
# カウント for(i in ch1){ if(str ~ ch1[i]){ ch1s[str]++ str = ch1str break } } for(i in ch2){ if(str ~ ch2[i]){ ch2s[str]++ str = ch2str break } } array[str]++ # 時間での統計 pos=match($0, /[0-9][0-9]:[0-9][0-9]/) if(!pos) next timestr = substr($0, pos, RLENGTH) split(timestr,times,\":\")
if(str ~ ch1str){ acc1[array[str]] = timestr acc1h[times[1]+1] = array[str] } if(str ~ ch2str){ acc2[array[str]] = timestr acc2h[times[1]+1] = array[str] } } END { # 最終統計データ print \"Start of acc\" print array[ch1str] \" : \" ch1str print array[ch2str] \" : \" ch2str print \"Others...\" for(i in array){ if(ch1str ~ i) continue if(ch2str ~ i) continue print array[i] \" : \" i } #使った名前出力 names=ch1str sep = \"::\" for(i in ch1s){ names=names sep i sep=\";\" } print names names=ch2str sep = \"::\" for(i in ch2s){ names=names sep i sep=\";\" } print names # code 重複の出力 for(i in codes){ if((codes[i]+0)>1){ print i \" \" codes[i] } } print \"End of acc\" # キャラ1の名前リスト print \"Start of 1stName\" for(i in ch1s){ print i \" \" ch1s[i] } print \"End of 1stName\" # キャラ2の名前リスト print \"Start of 2ndName\" for(i in ch1s){ print i \" \" ch2s[i] } print \"End of 2ndName\" # キャラ1の時間統計 print \"Start of 1st\" for(i = 1; i <= array[ch1str]; i++){ print acc1[i] \" \" i } print \"End of 1st\" # キャラ2の時間統計 print \"Start of 2nd\" for(i = 1; i <= array[ch2str]; i++){ print acc2[i] \" \" i } print \"End of 2nd\" # キャラ1の時間統計 print \"Start of 1stTime\" print 0 \" \" acc1h[1] for(i = 2; i <= 22; i++){ print (i-1) \" \" (acc1h[i] - acc1h[i-1]) } print 22 \" \" (acc1h[24] - acc1h[22]) print \"End of 1stTime\" # キャラ2の時間統計 print \"Start of 2ndTime\" print 0 \" \" acc2h[1] for(i = 2; i <= 22; i++){ print (i-1) \" \" (acc2h[i] - acc2h[i-1]) } print 22 \" \" (acc2h[24] - acc2h[22]) print \"End of 2ndTime\" }

count.sh:

export CH1STR=$1 export CH2STR=$2
EXECAWK=\"awk -F :: /$1/{print\$2}\" export CH1ALL=`cat names.txt | $EXECAWK`
EXECAWK=\"awk -F :: /$2/{print\$2}\" export CH2ALL=`cat names.txt | $EXECAWK` export DATE=$3
cat $4 | nkf --euc | awk -f count.awk | nkf --sjis

name.txt:

Reimu::霊夢;巫女;夢;神社;結界;reimu;28.6%;ハクレイのミコ;ハクレー;紅白;ミコミコレイーム;二色刷り;六位;瞬
Alice::アリス;リス;マーガトロイド;人形;七色;alice;ありしゅ;Alice;トロ;蟻さん;ありす;株式会社チャンピオンソフト;蹴りス;チャールズ・ラトウィッジ・ドジスン;カシューチャ;樋口 橘;ホライ
Marisa::魔理沙;黒くて;沙;マスタースパーク;Missile;魔法使い;マリ;恋符;恋の;旧ゴキブリ;まりさ;宴会の幹事;黒いの;霧雨;和食派;魔砲使いの人;恋色マジック;禿げ;スターダストレヴァリエ;黒
Fran::フラン;妹;ン
;腐乱;いもーとさま;紅月ふらん;495;ふらんちゃん;レーヴァテイン;乳臭い俺の嫁 Yuyuko::ゆゆさま;西行寺;幽々子;@;ゆゆこ;ゆゆ様;ユユサマー;おまえはすでに死んでいる;西行法師;ユユコサマ Remy::スカーレット;レッド;レミィ;レミリア;れ
;れみり;紅魔;ハート様大ブレイク;クイーン・オブ・ミッドナイト;姉紅;姉様;スピア・ザ・グングニルの使い手
★下記に2つの英単語をスペースで区切って入力してください

Home > プログラミング > 最萌トーナメントの集計スクリプト

Search
Feeds

Page Top