Just another Ruby porter,


6月下旬の日記 | RDF

2016-06-22 (Wed)

VirtualBoxの仮想マシンイメージがみつからない

といって立ち上がらなくなった。
原因はWindowsが勝手にシステム更新して強制的に再起動していたからなんだけど、
もうほんとやめて欲しい。ちょっと目を離した隙に要らんことをする。
それはそれとして、VMが置いてあるフォルダをみるとSolydx.vbox-tmpみたいな名前があるので、
これをSolydx.vboxと名前を変更してからVirtualBoxを立ち上げればok。


2016-06-21 (Tue)

Q5別解

awkだけでもいけそうだと思いついたのがこれ。

% gawk '12==a[$0=substr($1,1,4)]+=!$2' monthly_typhoon 
1984
1986
2000
2008

ただしmawkだと$0=substr($1,1,4)のほうが先に評価されて$2が常に空になるのでだめ。
というわけでこうしてみた。

% mawk '!$2&&12==++a[$0=substr($1,1,4)]' monthly_typhoon
1984
1986
2000
2008

ああ、だったらsubでYYYYMM 0のMM 0を空文字で置き換えて、
subの戻り値で置換したかどうかを判断すればよさげ。

% mawk 'sub(/.. 0/,"")&&++a[$0]==12' monthly_typhoon
1984
1986
2000
2008
% gawk 'sub(/.. 0/,"")&&++a[$0]==12' monthly_typhoon
1984
1986
2000
2008

これでgawk/mawkのどちらでも動き、しかも元の方法よりも短いしわかりやすくなった。


2016-06-20 (Mon)

Q1をjqで解く

その前に一昨日の日記にQ1の解を書いてなかった。

% awk -F, 'NR>1{for(i=2;i<NF;i++)printf "%d%02d %d\n",$1,i-1,$i}' landing.csv > monthly_typhoon
% head monthly_typhoon                                                                          
195101 0
195102 0
195103 0
195104 0
195105 0
195106 0
195107 1
195108 0
195109 0
195110 1
% tail monthly_typhoon
201503 0
201504 0
201505 0
201506 0
201507 2
201508 1
201509 1
201510 0
201511 0
201512 0

jqでも無理をすればなんとかなるようで。

% jq -R -r 'split(",")|[.[0]+(. as $a|range(1;13)|"0\(.) "[-3:]+$a[.])|sub(" $";" 0")]|join("\n")|select(test("^\\d"))' landing.csv > monthly_typhoon

肝はrange(1;13)|"0\(.) "[-3:]の部分で、"%02d "を意味している。

% jq -n -c 'range(1;13)|"\(.) "'
"1 "
"2 "
"3 "
"4 "
"5 "
"6 "
"7 "
"8 "
"9 "
"10 "
"11 "
"12 "
% jq -n -c 'range(1;13)|"0\(.) "[-3:]'
"01 "
"02 "
"03 "
"04 "
"05 "
"06 "
"07 "
"08 "
"09 "
"10 "
"11 "
"12 "

それをRubyで表現するとこんな感じ。

% ruby -anF, -e 'puts (1..12).map{|i|$F[0] + "%02d "%i + $F[i]}.map{|i|i.sub(/ $/, " 0")}.select{|x|x=~/^\d/}' landing.csv > monthly_typhoon

2016-06-19 (Sun)

BOMを消す

nkfじゃなくても3バイト削るだけなのでBOMを消す方法はいろいろある。

tail -c +4
dd bs=1 skip=3
sed '1s/^\xEF\xBB\xBF//'
LANG=ja_JP.UTF-8 sed '1s/^.//'
LANG=C sed '1s/^...//'

LANGがja_JP.UTF-8ならBOMも1文字と見做される。


2016-06-18 (Sat)

第23回シェル芸勉強会に参加

【問題】第23回梅雨でモワッとしたシェル芸勉強会 – 上田ブログ
というわけで梅雨とは思えない暑さの中行ってきた。
今回はオープンなデータを扱うawkまつりだった。
最大の敵はファイル名の長さだった。twitter的には非常につらい。

_ Q1:

これは準備。YYYYMM 上陸頻度という形式。
後々の問題のためにはYYYY MMのように空白があったほうがよかったいう意見がちらほら。

_ Q2 年ごとの台風の上陸頻度の確認:

年ごとなので上位4文字をキーにして頻度を集計。
CSVのほうは上陸してない年は0ではなく空文字なので、
$NF+0しておく必要がある。+$NFでもいい。
cmpなので何も表示されなければok。

% awk '{h[substr($1,1,4)]+=$2}END{for(i in h)print i,h[i]}' monthly_typhoon|sort|cmp - <(awk -F, 'NR>1{print $1,+$NF}' landing.csv)

_ Q3 各月の台風上陸確率:

月ごとなので年は不要。ここでも+することで0-prefixを削除している。

% awk '$2{m[+substr($1,5)]++}END{for(i=1;i<=12;i++)printf "%2d %5.2f%%\n", i,m[i]*100/NR*12}' monthly_typhoon
 1  0.00%
 2  0.00%
 3  0.00%
 4  1.54%
 5  3.08%
 6 13.85%
 7 40.00%
 8 63.08%
 9 63.08%
10 20.00%
11  1.54%
12  0.00%

_ Q4 各年で最初に台風が上陸した月を抽出し、何月が何回だったか集計:

landing.csvを使うとこんな感じ。-F,することでNFが,の数になり、それが最初の月になる。

% sed 's/,[1-9].*//' landing.csv | awk -F, 'NR>1&&NF<14{print NF}'|sort -n|uniq -c
      1 4
      2 5
      9 6
     21 7
     19 8
      7 9
      2 10

monthly_typhoonだったらこんな感じ。また+だ。

% awk '$2&&!a[substr($1,1,4)]++{print +substr($1,5)}' monthly_typhoon|sort -n|uniq -c 
% sed 's/\B/ /4' monthly_typhoon | awk '$3&&!a[$1]++{print +$2}'|sort -n|uniq -c

_ Q5 台風が上陸しなかった年を抽出:

landing.csvを使うのは禁止。
xargsを使い1年を1行にして、行頭のだけ残してYYYYMM を削除。
YYYY01 000000000000が消せればそれが上陸しなかった年。

% xargs -n24 < monthly_typhoon | sed -n  's/ [0-9]\{6\} //g;s/01 0*$//p'
1984
1986
2000
2008

_ Q6 各区で何件ずつレコードがあるか確認:

ひねりなし。

% cut -f1 -d' ' hittakuri|sort|uniq -c 
     56 大阪市中央区
      9 大阪市住之江区
     29 大阪市住吉区
     53 大阪市北区
     23 大阪市城東区
      7 大阪市大正区
     20 大阪市天王寺区
     33 大阪市平野区
      8 大阪市旭区
     22 大阪市東住吉区
     18 大阪市東成区
     17 大阪市東淀川区
      1 大阪市此花区
     22 大阪市浪速区
     31 大阪市淀川区
      6 大阪市港区
     31 大阪市生野区
      9 大阪市福島区
     28 大阪市西区
     37 大阪市西成区
      8 大阪市西淀川区
     15 大阪市都島区
     19 大阪市阿倍野区
      6 大阪市鶴見区

_ Q7 各区の人口当たりのひったくり件数のランキング:

population_h27sepをpという連想配列に読み込む。
引数にf=1を挟むことでフラグとして使える。
-(標準入力)を読み込む前にf=1になる。

% cut -f1 -d' '  hittakuri|sort|uniq -c|awk '!f{p[$1]=$2}f{printf "%7.3f%% %s\n", $1*100/p[$2],$2}' population_h27sep f=1 -|sort -nr
  0.059% 大阪市中央区
  0.045% 大阪市北区
  0.034% 大阪市西成区
  0.034% 大阪市浪速区
  0.031% 大阪市西区
  0.027% 大阪市天王寺区
  0.024% 大阪市生野区
  0.022% 大阪市東成区
  0.019% 大阪市住吉区
  0.018% 大阪市阿倍野区
  0.018% 大阪市淀川区
  0.017% 大阪市東住吉区
  0.017% 大阪市平野区
  0.015% 大阪市都島区
  0.014% 大阪市城東区
  0.013% 大阪市福島区
  0.010% 大阪市東淀川区
  0.010% 大阪市大正区
  0.009% 大阪市旭区
  0.008% 大阪市西淀川区
  0.007% 大阪市港区
  0.007% 大阪市住之江区
  0.005% 大阪市鶴見区
  0.001% 大阪市此花区

_ Q8 同一住所で同日に2件以上ひったくりが起こった場合について、その住所と日付を出力:

cutでもawkでもいいと思うが、cutのほうが指定が簡単。

% cut -d' ' -f1-3,8-10 hittakuri|sort|uniq -d
大阪市北区 曾根崎 2丁目付近 2015年 4月 13日
大阪市北区 角田町 付近 2015年 11月 4日
大阪市淀川区 十三本町 1丁目付近 2015年 4月 16日

_ Q9 ひったくりの手段とその成功率:

既遂が成功で手段が自転車とか。
/既遂/だとむだに0のときも足してるが場合分けしてないのでb[$7]++もいっしょに書ける。

% awk '{a[$7]+=/既遂/;b[$7]++}END{for(i in a)printf "%f %s\n", a[i]/b[i],i}'  hittakuri | sort -nr 
0.954225 自動二輪
0.942308 徒歩
0.920530 自転車
0.904762 自動車


6月下旬の日記 | RDF


WWW を検索 jarp.does.notwork.org を検索

わたなべひろふみ
Key fingerprint = C456 1350 085F A320 C6C8 8A36 0F15 9B2E EB12 3885
Valid HTML 4.01!