2013年4月13日土曜日

家に帰ってブログ書くまでがシェル芸



春爛漫シェル芸人撩乱勉強会に参加してきた。
本日はwget, curl, sedさんたちが活躍する内容。 curlなんて入ってたっけ?と思うぐらい何もしない状態での参加をしてしまった。
 前回と同じく以下、自分の知らなかったことの(断片的な)まとめ。

curl, wget で画像URL収集

curl, wgetでhtmlファイルを持ってきて、そこからは必要なデータを切り出すという作業。
以下はimgタグにある画像データを取ってくる場合。

$ curl http://www.yahoo.co.jp | sed -e 's/<img src/\n&/g' | grep "img src" | grep http | sed -e 's/^[^"]*"//' | sed -e 's/".*$//'

http://k.yimg.jp/images/clear.gif
http://k.yimg.jp/images/clear.gif
http://k.yimg.jp/images/clear.gif
http://k.yimg.jp/images/clear.gif
・・・以下略

上のコマンドを見て気持ち悪いと持った人は正常な感性を持ってると思う。オレならこう書けるとか思った人は変態やと思う。

ひたすらsedでテキストをいじってるけど、このURL抜き出しに必要なsedイディオムは以下のようだった。
  • img srcタグ1つにつき1行にするように抜き出したいタグ(この場合img)の前に改行をぶちこむ
  • 先頭からURLの直前の'"'までと、URL以降を削除する。
正規表現は普通に書くと最長一致となり意図しない部分まで削られてしまうので、 ^[^"]*"のような気持ち悪い書き方になる。これは何とかならない物なのか。

grep -oオプションを使えばもう少し簡単にかけて、以下のような感じになった。
$ curl http://www.yahoo.co.jp | sed -e 's/<img src/\n&amp//g' | grep "img src" | grep -o 'http://[^"]*"' | tr -d \"


-oオプションは行単位ではなく、マッチした部分のみ出力する。これは一番明日から使える内容かもしれない。 

いずれにしろ、こういう書き方はワンライナーだから許されるものであってこんなのがスクリプトとして残っていたら見るほうが発狂しそう。

あと便利なgrepオプションついでに-A -B -C (NUM)オプションも素晴らしい。これはマッチした行の前後もあわせて表示すると言うもの。

% seq 1 10 | sort -R
% seq 100 110                                           
100
101
102
103
104
105
106
107
108
109
110

# マッチした次の行も表示
% seq 100 110 | grep -A 1 105
105
106
# マッチした前の行も表示
% seq 100 110 | grep -B 1 105  
104
105
# マッチした前後の行も表示
% seq 100 110 | grep -C 1 105 
104
105
106


curl, wgetでPOSTリクエスト

以下のようにすれば、wget, curlでもPOSTリクエストが送れる。 cronで定期的にリクエスト投げたいときに使えるかもしれない。
$ wget -O - --post-data=test http://www.usptomo.com/XXXXXXX
$ curl -d test  http://www.usptomo.com/XXXXXX


他にもいろいろあったけど、とりあえず酒が入ってものすごい眠いので今日はここまで!