黒縁眼鏡は海を飛ぶ

IT中心にそこはかとなく

「第16回春だからログ解析するぞシェル芸勉強会」に行ってきた -大阪サテライト-

忙しい人向け

ゆっくりできる人向け

4/18(土)、第16回となるシェル芸勉強会が開催されました。
今まで参加したことがなかったのですが、大阪でリモート参戦できるということで参戦して参りました。
Ustで様子を放送していただけるので、Twitterのシェル芸タグで様々な方の足掻く様子アドバイスなど見れるので非常に良いですね。

大阪サテライトでは、@kunst1080さん主催の元、@mikkun_jpさんのお二方がプロジェクターなど会場の準備をしてくださいました。
お礼申し上げます。
大阪では私を除き、6名のシェル芸人の先輩方がいらっしゃいました。  

会場到着後の一幕。

店員さん「いらっしゃいませ。ご予約名をお願いします。」
参加者の方「USP友の会の勉強会が・・・」
店員さん「US…えっともう一度お願いできますか?」
私「あ、シェル芸勉強会です!」
店員さん「しぇ、しぇるげい???????」

だめでした。

ちゅうい

この記事では勉強会で出題された問題の一部を再度解いていきますが、私のシェル芸力不足故、手も足も出なかった問題は@ryuichiueda先生の解答を引用させていただいております。

解答を記載しておりますので、「俺は自力で解くぜ!!」という方は閲覧してはいけません!

準備という名のラスボス

この日のお題は「Apacheのログをシェル芸でログログする」でした。
事前に用意されているApacheのログを勉強会用に準備する際、日本の各地で阿鼻叫喚の様相(省略

準備1

199.72.81.55 - - [01/Jul/1995:00:00:01 -0400] "GET /history/apollo/ HTTP/1.0" 200 6245

これを

19950701 000001 199.72.81.55 - - [01/Jul/1995:00:00:01 -0400] "GET /history/apollo/ HTTP/1.0" 200 6245

このように正規化しておきましょう、というもの。

これを解決するワンライナーは以下。(引用)

$ awk '{print $4,$0}' access.log_shellshock |
  sed 's/^\[//' | 
  awk '{gsub(/[\/:]/," ",$1);print}' |
  sed -e 's/Sep/09/' -e 's/Oct/10/' -e 's/Nov/11/' -e 's/Dec/12/' |
  sed 's;^\(..\) \(..\) \(....\) \(..\) \(..\) \(..\);\3\2\1 \4\5\6;' > danger_log

1行目で第4フィールドにある年月日時を先頭に持ってきています。
awk$0は読み込んだ1行を表すんですね、勉強になります。 2行目で先頭につく邪魔な[を削除しています。ここまではまだ大丈夫。

3行目、awkgsubなるものを使っていますね。調べましょう。

gsubとは

文字列を置き換えます。見つかった所は、全部置き換えます。

o 対象文字列を直接変更しますので、必要な時は、値をコピーしてから使います。
o 最初の1つだけを置き換えたい時は、「sub = 文字列を、最初の1つだけ置き換える」

/[\/:]/の部分で第1フィールドの/もしくは:をスペースに置換しているんですね。
awkだとこういうこともできると。便利すぎる。

4行目で月を数値に置換した後、5行目でYYYYMMDD hhmmssの形式に直しています。

準備2

NASAのログを各日付のファイルに分けておきましょう。

これはいけそう…?と思ったのが以下。

$ for i in `awk '{print $1}' nasa.log | uniq` ; do grep $i nasa.log >> $i.log

かなり時間がかかる…

解答では

$ cat nasa.log | awk '{print $0 > $1}'

まじですか…

Q1

NASAのログについて、各ステータスコードの数を数えてみよう。

awkNFと、ステータスコードが後ろから数えて2フィールド目にあることから、

$ cat nasa.log | awk '{print $(NF-1)}' | sort | uniq -c

awkNFは、扱っているレコードのフィールド数が格納されている変数。
NRは、何レコード目をawkが扱っているかが格納されている変数。
awk便利すぎじゃね…

Q3

Q3-1.NASAのログについて、ログの件数が一番多い曜日はどれか。

この日の学びの一つであるdate -fがすごかった問題。

$ awk '{print $1}' nasa.log | date -f - "+%a" | sort | uniq -c

dateの部分で、+%wでも曜日だけが出力されます。

Q3-2.ログの件数が多い時間帯はどの時間帯か。

どうやって時間部分を抽出しよう…と悩んでいましたが、awksubstrが素晴らしかったです。

$ awk  '{print substr($2,1,2)}' nasa.log | sort | uniq -c

substrは選択したフィールドの文字列を開始位置から終了位置を指定して抽出できます。

とりあえずここまで

記事にはできていませんが、いちおう日曜日を使ってQ7まで全て復習できました。
勉強会1日を通して思ったことを列挙しておきます。

  • sed,awkを正しく使えるようになるととっても強力
  • 正規表現を正しく使えるようになるととっても強力
  • 上記2つを使えないとシェル芸を扱うことは難しいっぽい(特にawk)
  • シェル芸を通して、色々な方が足掻く交流できるとても良い場
  • シェル魔人はイケメン
  • 世の中には本当にワンライナーで大概のことを一撃で終わらせる達人が多数いる
  • シェル芸本、めっちゃ楽しみにしてます。
  • フォーク爆弾ステッカーいっぱいもらいました!

最後に、勉強会を主催してくださった皆々様方に感謝を。

大阪の皆様、コミュ障を遺憾なく発揮してしまい、かつ懇親会にも行けなかったため、あまりお話できなくて無念でなりません…
次回もきっと参加させていただきたいと思いますので、その際は是非ともよろしくお願い致します。ありがとうございました。

なお、許可をいただかずに色々と載せてしまっていますが、「それ困る」という箇所がありましたらご指摘くださいませ。

こ、怖くないですよ。