Your SlideShare is downloading. ×
awk v.s. bashどっちが強い?@OSC2011Tokyo
Upcoming SlideShare
Loading in...5
×

Thanks for flagging this SlideShare!

Oops! An error has occurred.

×

Introducing the official SlideShare app

Stunning, full-screen experience for iPhone and Android

Text the download link to your phone

Standard text messaging rates apply

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

6,436
views

Published on

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

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

Published in: Technology

1 Comment
10 Likes
Statistics
Notes
No Downloads
Views
Total Views
6,436
On Slideshare
0
From Embeds
0
Number of Embeds
3
Actions
Shares
0
Downloads
30
Comments
1
Likes
10
Embeds 0
No embeds

Report content
Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
No notes for slide

Transcript

  • 1. 「シェルスクリプト VS AWK」 どっちが強い!? プログラミングバトル日本 gnu awk ユーザー会 斉藤博文 USP友の会 上田隆一
  • 2. この発表• awk と シェルスクリプト(bash) の対決 – どっちが強い?(小学生風) – 同じお題をawkとシェルスクリプトで書く • スクリプトの華麗さを競う – 対決者 • awk: 斉藤博文(日本 gnu awk ユーザー会) – @hi_saito • シェルスクリプト: 上田隆一(USP友の会) – @usptomo, @ryuichiueda2011年11月19日 OSC2011 Tokyo Fall 2
  • 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. bashスクリプト• シェルスクリプト – 手で端末に打つコマンドをファイルに書くだけ• bash – Linux標準、使ったこと無い人はいないはず• コマンド使い放題 – 超高級プログラミング言語としての側面 • 処理の大半はコマンドに任せる • bashを端末を叩く人はみんなプログラマ アイコン?マスコット? んなもん無い。 2011年11月19日 OSC2011 Tokyo Fall 4
  • 5. 本日のお題• Round 1 小技: apache logさばき• Round 2 中技: CGIで何かアピール• Round 3 フリー演技2011年11月19日 OSC2011 Tokyo Fall 5
  • 6. 1回の表 (ノーアウト) Apache のログ解析の極意 FS にダブルクォート (") を使え!• ダブルクォートを FS にすると・・・ – $1:アクセス元、日付 ほとんどの – $2: 受け取ったコマンド 解析が便利に – $3: ステータスコード なるよ! – $6: クライアント情報2011年11月19日 OSC2011 Tokyo Fall 6
  • 7. 1回の表 (1 アウト) ログ解析の極意 awk だけに頼るな!御題 最も多く 404 を返しているサイトを探せ!• awk だけで書こうとすると結構大変かも。• shell のパイプで繋げるとデバッグもしやすいね。2011年11月19日 OSC2011 Tokyo Fall 7
  • 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. 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. 1回の表 (2 アウト) バッファに溜まって出力されない? system() は fflush() することをうまく使え! 御題リアルタイムで IP アドレスからホスト名を引け!$ tail -f access_log | awk {system ("dig -x" $1 " +short")} 2011年11月19日 OSC2011 Tokyo Fall 10
  • 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. 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. 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. 2回の表 (ノーアウト) awk で CGI を作る時の極意 GET と POST を意識せよ!最近の LL だと GET と POST を意識しなければいけないのはオワコンかもしれないけど、知って損なし。2011年11月19日 OSC2011 Tokyo Fall 14
  • 15. 2回の表 (1 アウト) 御題 日々の体重を記録せよ!• 体重を入力すると、グラフにしていってくれる。• スマートフォンでアプリ化するほどのものでも ないよね。2011年11月19日 OSC2011 Tokyo Fall 15
  • 16. 2回の表 (1 アウト) グラフの極意 Gnuplot を使いこなせ!• 手軽 munin とか• テキストベースで扱える Webalizer の• 出力の種類が多い ようなものも 作れる!2011年11月19日 OSC2011 Tokyo Fall 16
  • 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. 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. 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. 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. 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. 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. 2回の裏• ドリルダウン機能つきの表(USP研究所のデモから) – bashで書いたCGIスクリプト • ユーザの操作履歴をPOSTで受ける • 操作履歴から表示するレコード、開閉ボタンを準備 • htmlのテンプレートに貼り付けて出力 もっと派手なものが 見たければブースへ!!2011年11月19日 OSC2011 Tokyo Fall 23
  • 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. 3回の表 (そして伝説へ・・・) 電卓を作る極意! 好きな言語で記述せよ!calc() {awk "BEGIN {print $*}"}• これ、マジ便利です!• Perl, Ruby, Python, etc. 自分の好きな言語でどうぞ! 2011年11月19日 OSC2011 Tokyo Fall 25
  • 26. 3回の表 (そして伝説へ・・・) shell を作る極意! 100 % ネタです!awk {system($0)} 2011年11月19日 OSC2011 Tokyo Fall 26
  • 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. 3回の表 (そして伝説へ・・・) は 細 に 詳 ス ブ ーGo!CMS を作る極意! 根気と気合です! 全て awk で記述された Blis を改良 • し、RSS も生成するようにしてある。2011年11月19日 OSC2011 Tokyo Fall 28
  • 29. 3回の表 (そして伝説へ・・・) は 細 に 詳 ス ブ ーGo!ImageMagick を扱う極意! 文字コードを UTF-8 に揃えよ! • UTF-8 ならコマンドラインから文字 列を指定して、年賀状とか書けちゃう よ。2011年11月19日 OSC2011 Tokyo Fall 29
  • 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. 3回裏(伝説なのか?)• webから数値参照で書かれた文字列を 取ってくる。 #!/bin/bash curl $1 | grep &# | w3m -dump -T text/html2011年11月19日 OSC2011 Tokyo Fall 31
  • 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. 3回裏(伝説なのか?)• ブースにて、bashで書かれたシステムを お見せします。2011年11月19日 OSC2011 Tokyo Fall 33
  • 34. まとめ• awkなしでシェルスクリプトを書くのは大変だね• シェルスクリプトと awk で世界が広がるよ – ということで友好団体になりました。• 質問はブースへ – 隣同士にいます。2011年11月19日 OSC2011 Tokyo Fall 34