LoginSignup
3
3

More than 5 years have passed since last update.

第23回梅雨でモワッとしたシェル芸勉強会

Last updated at Posted at 2016-06-20

タイトルの通りです。
コマンドプロンプトと自作コマンドを駆使して解けるところまで解いてみました。

【問題】第23回梅雨でモワッとしたシェル芸勉強会

とりあえずデータを取ってきます。
コマンドプロンプトでは bitsadmin というコマンドを使います。
見慣れない感じですが、標準コマンドだそうです。

Q0
bitsadmin /rawreturn /transfer get http://www.data.jma.go.jp/fcd/yoho/typhoon/statistics/landing/landing.csv %CD%\landing.csv

落ちてきたデータは UTF-8 のようなので変換します。
変換には iconv を使います。

Q0
iconv /f UTF-8 /o landing.sjis.csv landing.csv 

iconvADODB.Stream を呼び出すだけのコマンドです。出力文字コードを指定しない場合は Shift_JIS で標準出力に吐き出すので、上記のコマンドは iconv /f UTF-8 landing.csv > landing.sjis.csv と等価です。Shift_JIS 以外で出力するときは /o で一旦ファイルに落とす必要があります。

話がそれました。では問題に取り掛かります。

Q1

いきなりですが sed で黒魔術っぽいことをやります。12月までのデータが一行に並んでいるので、カンマを改行に置換しながら月毎に分割していきます。

Q1
type landing.sjis.csv | ^
sed /e "1d" | ^
sed /e "s/,/01 /" ^
/e "s/(\d{4})(.*?),/$1$2\n$102 /" ^
/e "s/(\d{4})(.*?),/$1$2\n$103 /" ^
/e "s/(\d{4})(.*?),/$1$2\n$104 /" ^
/e "s/(\d{4})(.*?),/$1$2\n$105 /" ^
/e "s/(\d{4})(.*?),/$1$2\n$106 /" ^
/e "s/(\d{4})(.*?),/$1$2\n$107 /" ^
/e "s/(\d{4})(.*?),/$1$2\n$108 /" ^
/e "s/(\d{4})(.*?),/$1$2\n$109 /" ^
/e "s/(\d{4})(.*?),/$1$2\n$110 /" ^
/e "s/(\d{4})(.*?),/$1$2\n$111 /" ^
/e "s/(\d{4})(.*?),/$1$2\n$112 /" ^
/e "s/,.*//" > monthly_typhoon

Q2

さらに闇が深まりました。もはや何が起こっているのか自分でも理解できません。元データと変換データの突き合わせ検証をしているらしいです。最後の 3 行だけ解説すると、 '元データの合計値'=='変換データの合計値' という式を作り、 eval に突っ込んだ結果 false となった行だけ出力しようとしています(この場合は全て true となり何も出力されません)。

Q2
type monthly_typhoon | ^
sed /e "s/^(\d{4})\d{2}/$1/;$d" | ^
sed /e "N;N;N;N;N;N;N;N;N;N;N;s/\r\n//g" ^
/e "s/\d{4} / /g" ^
/e "s/ +/\+/g" ^
/e "s/\+$/+0/" | ^
xargs /n 1 eval | ^
sed /e "1i hoge" | ^
paste landing.sjis.csv - | ^
sed /e "s/^.*,//" ^
/e "s/^\t/0\t/" | ^
sed /e "1d" ^
/e "s/\t/==/" | ^
xargs /n 1 eval | ^
findstr false

Q3, Q4, Q5

諦めました。

Q6

簡単でした。

Q6
type hittakuri | ^
cut /d , /f 1 | ^
sort | ^
uniq | ^
(for /f "usebackq" %i in (`findstr .*`) do @( findstr %i hittakuri | wc /l | xargs /I @ echo %i @ ))

Q7

作成中の join を使いました。ところで wc がタブを出力していることに気付いたんですが、この挙動は一般的なんでしょうか。tr で簡単に置換できるので気になりませんが。

Q7
type hittakuri | ^
cut /d , /f 1 | ^
sort | uniq | ^
(for /f "usebackq" %i in (`findstr .*`) do @( findstr %i hittakuri | wc /l | xargs /I @ echo %i @ )) | ^
tr "\t" " " | ^
join - population_h27sep | ^
sed /e "s/  .* /\//" /e "s/^(.*) (.*)$/'$1 ' + \($2\)/" | ^
xargs /n 1 eval | ^
msort /k 2nr

Q8

ちょろいですね。

Q8
type hittakuri | cut /d , /f 1,2,3,8,9,10 | sort | uniq /c | findstr /v "^1" | cut /d " " /f 2

Q9

諦めました。

おわりに

windows で awk に相当するコマンドが思いつかず、集計がうまくできませんでした。awk だと hoge[$1] += 1 で簡単に集計できるので連想配列は便利ですね。また forEND が使えるのも awk の強みだと思います。やはり awk は偉大。

そういえばコマンドプロンプトから powershell を呼び出せることに今気づいたのですがもしかして。。。

3
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
3