ABOUT

イベント・勉強会

Tech LION

USP Magazine

外部サイト

Twitter

 前へ
 次へ
投稿者: USPMAG編集長   2012年03月28日 06:37    タグ: bash Tukubai OSC

ドキドキ☆素敵な、シェルスクリプトの世界@OSC ― その2

水鳥だらけの水泳大会
こんにちは、ふたたびUSP MAGAZINE編集長のまつうらです。いやぁ花見シーズンもうすぐ到来ですねー。自宅近くを流れる河辺のサクラは品種によってはもう満開でした。そして、水上はユリカモメを始めとする水鳥だらけで、毎日水泳大会を開いております。

というわけで、強引に「○○だらけの○○大会」のテンプレートに話を持っていったわけですが、何が言いたいのかと言うと前回の記事の続きです。その名も!

ドキドキ☆コマンドだらけのシェルスクリプト大会、JOINもあるよっ!

なんなんですか、このタイトルは!!またもオカシなタイトルを……。って、私が勝手に付けました。スミマセン。先日のOSC2012 Tokyo/Springで講演された本当のタイトルは「さわって☆ドキドキ。こんなに素敵♥なシェルスクリプト。」です。……どっちもどっちですね。(・・;

あれはどーなった?

そうそう、まず解決しなきゃならないお題がありました。

ある年月の一か月間の日付を、YYYYMMDD形式で全て列挙せよ。ただし、引数からYYYYMMを受け取るものとする。(例えば2012年1月なら、201201という引数が与えられ、出力は20120101、20120102、…、20120131となる)
これに対し、Linuxに標準で備わっているコマンドだけで答えると、このくらいの短さが限界で、制御構文が取れないよーといって終わっていたのでした。
	n="${1}01"
	m="${1}99"
	while [ $n -lt $m ] ; do
		echo $n
		n=$(date -d "$n 1 day" +%Y%m%d)
	done
シェルスクリプト高速化のカギは、いかに制御構文を減らしてコマンドに任せるかなのです。リーダーは頭を使うのが役目であり、自ら奔走すべきではないのです。

Tukubai使って華麗に解決

そこで!そんなシェルスクリプターなあなたの手足となって働くべく開発されたコマンドセットがTukubaiなのです。そしてその中から、「一軍選手」たる使用頻度の高いコマンドをオープンソース版として公開したものがOpen usp Tukubaiというわけです。Open版はPythonで書き直されており、いぢり易さがウリです。「こんなふうに改造してみてはどうか」という意見を広く募れればいいなと思っています。

前置きが長くなりましが、そんなわけでTukubaiコマンドを使うとキレイになります。日付計算にはmdateというコマンドを用います。UNIX系OSに標準で入っているdateコマンドは、各OSによって機能に差異があったり書式に方言もあったりするので現在日時を調べるくらいにしか使いません。
-eオプション(列挙を表すenumerateの意)を付けて、YYYYMMDD形式の日付と、後ろに"/+30"を付けてやると、YYYYMMDDで指定した年月日と、そこから30日後までの日付を列挙してくれます。

	mdate -e "${1}01/+30"
201202(2012年02月)だとこんなふうになります。
20120201 20120202 20120203 20120204 20120205 20120206 20120207 20120208 20120209
 20120210 20120211 20120212 20120213 20120214 20120215 20120216 20120217 2012021
8 20120219 20120220 20120221 20120222 20120223 20120224 20120225 20120226 201202
27 20120228 20120229 20120301 20120302
おっと。これだと2月や4月等、一か月が31日間無い月は翌月まで表示されてしまいます。月が替わっているところがあったら削らなきゃいけませんね。でも、for文で1つ1つチェックしてしまっては意味がありません。こういう時はまず縦に並べます。trコマンドを使って "tr ' ' '\n'" とやってもいいのですが、Tukubaiにはtateyokoなんていう縦横変換(数学用語で言うと転置)をしてくれるコマンドがあったりしますので、これを使います。
	mdate -e "${1}01/+30" |
	tateyoko
すると、先程の2012年02月はこんなふうになります。
20120201
20120202
20120203
   :
20120229
20120301
20120302
下の2行が余計です。邪魔な行を消したければgrepを使えばいいわけです。はいできあがり。
	mdate -e "${1}01/+30" |
	tateyoko              |
	grep "^${1}"
グレイト!制御構文が消えました。

パイプが、シェルスクリプトを加速する!

パイプでマルチプロセッシング
上から下へ素直に読めるソースにもなってキレイじゃありませんか。え、「パイプでコマンドが3つもくっつけてるところがに違和感を覚える」って?いやいや、これが美しいのです!

見た目だけではありません。設計もです。シェルはパイプを作るとこまで関与しますが、作った後、中を流れるデータはコマンドプロセスやカーネルに全て任せ、自らは終わるまで一切関与しないから速いのです。しかも!パイプで繋がれたプログラムのプロセスは皆、同じ時期に生まれ同じ時代を生きてます。と、いうことは、パイプ使うだけであなたはマルチプロセッシングなコードを書いているのですよ。パイプを繋げば繋ぐほど、デュアルだクアッドだヘキサだオクタだ、そんなマルチコアCPUを簡単にしゃぶり尽くせるのです。

で、JOINはどこにあったの?

長くなったので、JOINの話はまた次回!エェー( ̄д ̄)!!!

オイシいところで引っ張るのは番組の常じゃありませんか。 続きが見たいという方は、このスライドを見てその先を予習しておきましょう。

ではさらば! 本当は前後編で終わらせる予定だったのに、講演内容を逸脱して話が長引いて一回増えることになってしまったのはヒミツだ。

↓押してね!

フリーワード検索

新着情報

タグ

人気ページ 2012年2月18日~