USP 友の会 LT 資料 20130413

3,133 views

Published on

1 Comment
23 Likes
Statistics
Notes
No Downloads
Views
Total views
3,133
On SlideShare
0
From Embeds
0
Number of Embeds
112
Actions
Shares
0
Downloads
31
Comments
1
Likes
23
Embeds 0
No embeds

No notes for slide

USP 友の会 LT 資料 20130413

  1. 1. USP 友の会 LT (2013/04/13) wget と curl で 並列ダウンロード  斉藤 博文  @hi_saito  hi_saito@yk.rim.or.jp
  2. 2. 自己紹介 斉藤 博文  日本 GNU AWK ユーザー会主宰  @hi_saito  hi_saito@yk.rim.or.jp  Shell + AWK 最強!
  3. 3. サイトから画像を一括並列ダウンロード ひとつひとつの画像をブラウザから右クリッ クで保存するのは面倒ですよね。 画像を抜き出して保存する専用アプリもある ようですが、「シェル芸」で十分です。 LL だと並列ダウンロードするのに fork とか を使いますが、使い方が良く分からないとい う人もいるんじゃないでしょうか。
  4. 4. 使うもの bash wget  curl でも可能ですが、今回の場合には wget の方が便利です。 tr egrep (grep) sort sed xargs
  5. 5. 手順を記述してみる1. 画像のあるサイトの HTML を落とす。2. アトリビュートを分割する。3. 画像を抜き出す。4. ダブっていたら無駄なのでダブらいないよう にする。5. 必要に応じて絶対 URL に変換する。6. 並列に分割して画像を落とす。
  6. 6. コードにしてみる$ wget -O - http://www.usptomo.com/ | tr """ "n" | egrep ".(JPG|PNG|GIF)" | sort -u | sed s|^|http://www.usptomo.com| | xargs -P0 -n1 wget xargs で -PN で N 並列実行ですが、-P0 で可能な限り並列実行します。 xargs の -nN で N 個単位で分割しますので、 -n1 だと結果的に全て並列処理になります。
  7. 7. ちょっとしたコツ HTML からリンク先を抜き出すには tr で分 割すると便利な場合が多いです。 egrep は括弧でグルーピングができるので拡 張子をまとめて記述することができます。  もちろん、tr と egrep を awk でまとめ て記述することもできます。
  8. 8. 並列分割ダウンロード 巨大なファイルをダウンロードしたい。 サーバーが 1 接続あたりの回線速度を制限し ているため十分な速度が出ていない。 並列分割ダウンロードする OSS はあまりな いよね。
  9. 9. 使うもの bash curl  今回は wget ではなく curl が必要です。 sed awk etc.
  10. 10. 手順を記述してみる1. 対象のファイルサイズを取得する。2. サイズを分割数で割る。3. ナンバリングして並列で落とす。4. 親プロセスは落とし終わるまで待つ。5. 分割したものを結合する。
  11. 11. 対象のファイルサイズを取得#! /bin/bashDIV=5URL=$1FILE=$(basename ${URL})PID=$$CONTENT_LENGTH=$(curl -s --head ${URL} | sed s|r|| | awk /^Content-Length/ {print $2}) curl は --head でヘッダーのみを取得でき ます。
  12. 12. サイズを分割数で割るfor i in `seq 1 ${DIV}`; do START_BYTE=$(echo "${CONTENT_LENGTH} / ${DIV} * (${i} - 1)" | bc) END_BYTE=$(echo "${CONTENT_LENGTH} / ${DIV} * ${i} - 1" | bc) if [ ${i} -eq ${DIV} ]; then END_BYTE=${CONTENT_LENGTH} fi 分割して落とす先頭バイト数と終了バイト数 を計算します。
  13. 13. ナンバリングして並列で落とす TMP_FILE=$(printf "%d-%02d-%s" ${PID} ${i} ${FILE}) curl -s --range ${START_BYTE}-${END_BYTE} -o ${TMP_FILE} ${URL} &done curl は --range で落とす範囲を指定するこ とができます。
  14. 14. 落とし終わるまで待って結合waitcat $$-* > ${FILE}rm -f $$-* wait 単独だと全ての子プロセスの終了を待ち ます。
  15. 15. USP 友の会 LT (2013/04/13) iPhone 用のカレンダー壁紙を作る  斉藤 博文  @hi_saito  hi_saito@yk.rim.or.jp
  16. 16. 使うもの bash  bash の記述を使っています。 cal awk convert (ImageMagick)
  17. 17. cal コマンドの基本形$ cal April 2013Su Mo Tu We Th Fr Sa 1 2 3 4 5 6 7 8 9 10 11 12 1314 15 16 17 18 19 2021 22 23 24 25 26 2728 29 30 cal コマンドは何も引数がないと今月のカレ ンダーを表示します。
  18. 18. ImageMagick で画像に変換$ convert -font Ricty-Bold.ttf -pointsize 40 -fill black -draw "text 120,450 "$(cal)"" iphone.png calendar.png ImageMagick は 日本語 TTF も扱え ます。 文字列だけでなく、 コマンドを埋め込め ます。
  19. 19. 日曜日だけを抜き出す$ cal | awk $0=substr($0, 1, 2)Su 7142128 この awk の使い方分かりますか? アクショ ンがないのに表示できていますよね。
  20. 20. アクションレスプログラミング awk はパターン + アクションですよね。 でも、アクションがない場合は {print $0} が省略されたものと見なれます。 また、awk では基本的に代入は「真」になり ます。$0=substr($0, 1, 2) 等価!{ $0 = substr($0, 1, 2); print $0;}
  21. 21. 土曜日だけを抜き出す$ cal | awk $0=sprintf("%20s",substr($0, 19, 2)) Sa 6 13 20 27 これもアクションレスプログラミングですね。 ここまでくれば、あとは同じです。
  22. 22. 最終形態$ convert -font Ricty-Bold.ttf -pointsize 40 -fill black -draw "text 120,450 "$(cal)"" -fill red -draw "text 120,450 "$(cal|awk $0=substr($0, 1, 2))"" -fill blue -draw "text 120,450 "$(cal|awk $0=sprintf("%20s",substr($0,19,2)))"" iphone.png calendar.png ほらね。「シェル 芸」でできるでしょ。
  23. 23. 特定の日付だけを出す方法は? 特定の日付だけを抜き出すことができれば、 今日や国民の休日をマーキングすることもで きますね。 土日と比べると複雑ですが、やってみてくだ$ cal | awk -v day="${DAY}" -v str="@" さい。{ regexp = "(^| )" day "( |$)"; $0 = gensub(regexp, "1@2", 1, $0);}{gsub(/[^@]/, " ")}{sub(/@/, day)}1
  24. 24. 最終的には? 最終的には cron に crontab で登録して毎 月 1 日に更新し、メールで iPhone に送る ようにすると便利です。

×