awk v.s. bashどっちが強い?@OSC2011Tokyo

8,212 views

Published on

OSC2011 Tokyo/Fallで、日本gnu awkユーザー会の斉藤さんと行ったプレゼンテーションです。awkとbashの馴れ合い、もとい、共存共栄がテーマです。

Published in: Technology
1 Comment
15 Likes
Statistics
Notes
No Downloads
Views
Total views
8,212
On SlideShare
0
From Embeds
0
Number of Embeds
1,181
Actions
Shares
0
Downloads
37
Comments
1
Likes
15
Embeds 0
No embeds

No notes for slide

awk v.s. bashどっちが強い?@OSC2011Tokyo

  1. 1. 「シェルスクリプト VS AWK」 どっちが強い!? プログラミングバトル日本 gnu awk ユーザー会 斉藤博文 USP友の会 上田隆一
  2. 2. この発表• awk と シェルスクリプト(bash) の対決 – どっちが強い?(小学生風) – 同じお題をawkとシェルスクリプトで書く • スクリプトの華麗さを競う – 対決者 • awk: 斉藤博文(日本 gnu awk ユーザー会) – @hi_saito • シェルスクリプト: 上田隆一(USP友の会) – @usptomo, @ryuichiueda2011年11月19日 OSC2011 Tokyo Fall 2
  3. 3. awk• 1977 年にできたスクリプト言語 – GNU awk は 1985 年• UNIX の創造者の英知の集合 – Alfred Aho – Peter Weinberger – Brian Kernighan• 実は awk は高速 – nawk << Ruby, Perl < gawk << mawk << C2011年11月19日 OSC2011 Tokyo Fall 3
  4. 4. bashスクリプト• シェルスクリプト – 手で端末に打つコマンドをファイルに書くだけ• bash – Linux標準、使ったこと無い人はいないはず• コマンド使い放題 – 超高級プログラミング言語としての側面 • 処理の大半はコマンドに任せる • bashを端末を叩く人はみんなプログラマ アイコン?マスコット? んなもん無い。 2011年11月19日 OSC2011 Tokyo Fall 4
  5. 5. 本日のお題• Round 1 小技: apache logさばき• Round 2 中技: CGIで何かアピール• Round 3 フリー演技2011年11月19日 OSC2011 Tokyo Fall 5
  6. 6. 1回の表 (ノーアウト) Apache のログ解析の極意 FS にダブルクォート (") を使え!• ダブルクォートを FS にすると・・・ – $1:アクセス元、日付 ほとんどの – $2: 受け取ったコマンド 解析が便利に – $3: ステータスコード なるよ! – $6: クライアント情報2011年11月19日 OSC2011 Tokyo Fall 6
  7. 7. 1回の表 (1 アウト) ログ解析の極意 awk だけに頼るな!御題 最も多く 404 を返しているサイトを探せ!• awk だけで書こうとすると結構大変かも。• shell のパイプで繋げるとデバッグもしやすいね。2011年11月19日 OSC2011 Tokyo Fall 7
  8. 8. 1回の表 (2 アウト)#! /bin/gawk -fBEGIN { FS = """;}$3 ~ / 404 / { split($1, arr, / /); count[arr[1]]++;}END { for (a in count) { stat_arr[i++] = sprintf("%010s", count[a]) " " a; } num = asort(stat_arr); split(stat_arr[num], url, / /); print url[2];}awk だけでできるけど、直感的じゃないよね。 2011年11月19日 OSC2011 Tokyo Fall 8
  9. 9. 1回の表 (2 アウト)$ cat access_log | awk -F " $3 ~ / 404 / | awk $0 = $1 | sort | uniq -c | sort -nr | awk NR == 1 && $0 = $2127.0.0.1 # オレかよ!!分かりやすいし、途中結果も確認しやすいね。 2011年11月19日 OSC2011 Tokyo Fall 9
  10. 10. 1回の表 (2 アウト) バッファに溜まって出力されない? system() は fflush() することをうまく使え! 御題リアルタイムで IP アドレスからホスト名を引け!$ tail -f access_log | awk {system ("dig -x" $1 " +short")} 2011年11月19日 OSC2011 Tokyo Fall 10
  11. 11. 1回の裏• シェルスクリプトでのログ処理 – データを正規化しておくと以後の処理が簡単に 000003795 1 114.182.31.102 000003795 2 - 000003795 3 - 000003795 4 20111106 162032 000003795 5 GET /usage/ctry_usage_201110.png HTTP/1.1 000003795 6 200 000003795 7 4168 000003795 8 http://www.araibo.com/usage/usage_201110.html 000003795 9 Mozilla/5.0 (X11; Linux i686; rv:7.0.1) Gecko/20100101 Firefox/7.0.1 000003796 1 66.249.66.18 000003796 2 - 000003796 3 - 000003796 4 20111106 164022 000003796 5 GET /paper/ARAIBO_TechnicalReport2006.pdf HTTP/1.1 000003796 6 200 000003796 7 1801153 000003796 8 - 000003796 9 Googlebot/2.1 (+http://www.google.com/bot.html)2011年11月19日 OSC2011 Tokyo Fall 11
  12. 12. 1回の裏 • 正規化スクリプト – ...結構awk依存#!/bin/bash -vxdir=/var/www/html/OSCtmp=/tmp/$$cat $dir/LOG/httpd/access_{log.*,log} |sed -e s/(..*) (..*) (..*) [(..*)] "(..*)" (..*)(..*) "(..*)" "(..*)"$/1ダァシェリイェス2ダァシェリイェス3ダァシェリイェス4ダァシェリイェス5ダァシェリイェス6ダァシェリイェス7ダァシェリイェス8ダァシェリイェス9/ |awk -F"ダァシェリイェス" {c=1;for(i=1;i<=NF;i++){print NR,c++,$i}} |awk {$1=sprintf("%09s",$1);print} > $tmp-dataawk $2==4 $tmp-data | tr /: |awk {print $4,$0} |sed -f $dir/SYS/MONTH |awk {print $2,$3,$6$1$4,$7$8$9}| sort -ms -k1,2 - $tmp-data |awk $2!=4 || $3!~/:/ > $dir/LOG/ACCESS_LOG 2011年11月19日 OSC2011 Tokyo Fall 12
  13. 13. 1回の裏• 続きは端末で – 404エラーを出したIP • $ cat ../LOG/ACCESS_LOG | awk $2==1 || $2==6 | awk {if($2==1){printf("%s ",$0)}else{print}} | grep "404$" | awk {print $3} | sort | uniq -c | awk {print $2,$1} | sort -k2,2n – 閲覧された回数 • $ awk $2==5 ../LOG/ACCESS_LOG | awk {print $4} | sort | uniq -c | egrep "cgi|php|htm|html" | awk {print $2,$1} | sort -k2,2n ※難しいでしょうか?? いや、出力見ながらパイプをつなげていくだけなので、 案外簡単です。2011年11月19日 OSC2011 Tokyo Fall 13
  14. 14. 2回の表 (ノーアウト) awk で CGI を作る時の極意 GET と POST を意識せよ!最近の LL だと GET と POST を意識しなければいけないのはオワコンかもしれないけど、知って損なし。2011年11月19日 OSC2011 Tokyo Fall 14
  15. 15. 2回の表 (1 アウト) 御題 日々の体重を記録せよ!• 体重を入力すると、グラフにしていってくれる。• スマートフォンでアプリ化するほどのものでも ないよね。2011年11月19日 OSC2011 Tokyo Fall 15
  16. 16. 2回の表 (1 アウト) グラフの極意 Gnuplot を使いこなせ!• 手軽 munin とか• テキストベースで扱える Webalizer の• 出力の種類が多い ようなものも 作れる!2011年11月19日 OSC2011 Tokyo Fall 16
  17. 17. 2回の表 (2 アウト)<html><head><title>AWK の CGI サンプル</title></head><body><form method="GET" action="graph.cgi"><input type="text" value="60" name="weight"><input type="submit" value="get"name="submit"></form></body></html>これは普通の HTML です。 2011年11月19日 OSC2011 Tokyo Fall 17
  18. 18. 2回の表 (2 アウト)#! /bin/gawk -f## graph.cgiBEGIN { data_file = "data.txt"; ORS = "rn"; split(ENVIRON["QUERY_STRING"], arr_query, "&"); for (i in arr_query) { split(arr_query[i], arr_query_val, "="); query_name = arr_query_val[1]; query_str = arr_query_val[2]; query[query_name] = query_str; }GET なので環境変数からデータを格納する。 2011年11月19日 OSC2011 Tokyo Fall 18
  19. 19. 2回の表 (2 アウト) now = strftime("%Y/%m/%d-%H:%M"); printf("%s %sn", now, query["weight"])>>data_file; close(data_file); print "set xdata timenset timefmt %Y/%m/%d-%H:%M:%Snset terminal pngnset yrange [0:100]nset xlabel Datenset ylabel Weight (Kg)nset output graph.pngnplot " data_file " using 1:2 title Weight withlinesnquitn" | "gnuplot > /dev/null";データを格納し、Gnuplot でグラフを描く。 2011年11月19日 OSC2011 Tokyo Fall 19
  20. 20. 2回の表 (2 アウト) は 細 に 詳 ス print "Content-Type: text/html"; ブ ーGo! print ""; print "<html><head><title>体重のグラフ</title></head><body><img src=graph.png></body></html>";}HTML を出力し、画面にグラフを表示する。 2011年11月19日 OSC2011 Tokyo Fall 20
  21. 21. 2回の裏• テキストの表をブラウザに出力してみる。 – コマンドにしてみました。 html_tableコマンド #!/bin/bash echo <table cellspacing="0" border="1"> sed -e s;^;t<tr>ntt<td>; -e s;$;</td>nt</tr>; -e s; ;</td>ntt<td>;g < /dev/stdin echo </table>2011年11月19日 OSC2011 Tokyo Fall 21
  22. 22. 2回の裏• すごく頑丈なアクセスカウンタを作ってきました。 #!/bin/bash -vx dir=/home/usp/ACCESS_COUNTER echo -n 1 >> $dir/POMPA/COUNTER echo "Content-type: text/htmln" ls -l $dir/POMPA/COUNTER | awk {print $5} exit 0 – HTTP出力込みでわずか6行 – 原理 • アクセスがあるとカウンタファイルを1バイト増やす • lsでカウンタファイルの容量を調べて出力 • 排他処理なんてイラネエ。あ、awkを使ってもうた。2011年11月19日 OSC2011 Tokyo Fall 22
  23. 23. 2回の裏• ドリルダウン機能つきの表(USP研究所のデモから) – bashで書いたCGIスクリプト • ユーザの操作履歴をPOSTで受ける • 操作履歴から表示するレコード、開閉ボタンを準備 • htmlのテンプレートに貼り付けて出力 もっと派手なものが 見たければブースへ!!2011年11月19日 OSC2011 Tokyo Fall 23
  24. 24. 3回の表 (そして伝説へ・・・) gawk で @include する極意! igawk は 100 % shell なので注意!eval gawk $opts -- "$processed_program" "$@"• 中間ファイルを作成しないように、直接ソースを gawk に食わせている ため、巨大なスクリプトを実行するとエラーになる。orz – comp.lang.awk の FAQ ・・・ 2011年11月19日 OSC2011 Tokyo Fall 24
  25. 25. 3回の表 (そして伝説へ・・・) 電卓を作る極意! 好きな言語で記述せよ!calc() {awk "BEGIN {print $*}"}• これ、マジ便利です!• Perl, Ruby, Python, etc. 自分の好きな言語でどうぞ! 2011年11月19日 OSC2011 Tokyo Fall 25
  26. 26. 3回の表 (そして伝説へ・・・) shell を作る極意! 100 % ネタです!awk {system($0)} 2011年11月19日 OSC2011 Tokyo Fall 26
  27. 27. 3回の表 (そして伝説へ・・・) は 細 に 詳 ス ブ ーGo! ppencode の極意! length() は length でエラーにならない! 0 : length1 : cos(length)2 : int(exp(cos(length)))3 : ...• length が引数なしでエラーにならないのはバグとして報告されている ので、いつか使えなくなるかも? 2011年11月19日 OSC2011 Tokyo Fall 27
  28. 28. 3回の表 (そして伝説へ・・・) は 細 に 詳 ス ブ ーGo!CMS を作る極意! 根気と気合です! 全て awk で記述された Blis を改良 • し、RSS も生成するようにしてある。2011年11月19日 OSC2011 Tokyo Fall 28
  29. 29. 3回の表 (そして伝説へ・・・) は 細 に 詳 ス ブ ーGo!ImageMagick を扱う極意! 文字コードを UTF-8 に揃えよ! • UTF-8 ならコマンドラインから文字 列を指定して、年賀状とか書けちゃう よ。2011年11月19日 OSC2011 Tokyo Fall 29
  30. 30. 3回裏(伝説なのか?)• 他の言語を使う。 – PYTHON.sh, C.sh, RUBY.sh, ...#!/bin/bash# エクセルシートのB列の値を足す。ruby << FIN | awk BEGIN{sum=0}{sum+=$1}END{print sum}require rubygemsrequire spreadsheetbook = Spreadsheet.open ./hoge.xlssheet = book.worksheet 0for i in 0..3 print sheet[i,1] print "n"endFIN2011年11月19日 OSC2011 Tokyo Fall 30
  31. 31. 3回裏(伝説なのか?)• webから数値参照で書かれた文字列を 取ってくる。 #!/bin/bash curl $1 | grep &# | w3m -dump -T text/html2011年11月19日 OSC2011 Tokyo Fall 31
  32. 32. 3回裏(伝説なのか?)• クローラを作ってきました。#!/bin/bash -vxmkdir -p ./cachecd ./cacheecho http://www.google.co.jp/ > ./url.1for i in 2 3 4 ; do cat ./url.$(( $i - 1 )) | wget -i - cat ./* | sed -e s|href="([^"][^"]*)"|n1n|g | grep ^http | sort | uniq                   > ./url.$idoneexit 02011年11月19日 OSC2011 Tokyo Fall 32
  33. 33. 3回裏(伝説なのか?)• ブースにて、bashで書かれたシステムを お見せします。2011年11月19日 OSC2011 Tokyo Fall 33
  34. 34. まとめ• awkなしでシェルスクリプトを書くのは大変だね• シェルスクリプトと awk で世界が広がるよ – ということで友好団体になりました。• 質問はブースへ – 隣同士にいます。2011年11月19日 OSC2011 Tokyo Fall 34

×