ワンライナー

夜な夜な自家発電に勤しんでいる中高生から中高年の皆様こんにちは。htmlソースにリンクがベタ書きされている静止画と違い、動画はcdnからの直リンク防止策が講じられているようです。しかしシェル芸人たるもの、ダウンロードのためだけにブラウザを開きっぱなしにするのはカッコ悪いですよね?さあワンライナーで動画をゲットしましょう!

[ (っ´∀`)っ@友の会 ~]$ URI=http://jp.xvideos.com/video〜〜〜/〜〜〜〜〜 ; wget -O $(basename ${URI}).flv $(curl -s ${URI} | grep flv_url | sed -e 's/%3A/:/g;s/%2F//g;s/%3F/?/g;s/%3D/=/g;s/%26/&/g;s/&/ /g;s/flv_url=//g' | awk '{print $11}')

動画のページを開いてソースを見てみると、flv_url=〜〜〜という箇所があって、ここが動画の埋め込み場所だということが判明しました。最初はリンク先の http://〜〜〜(cdnのURL)/ほにゃらら.flv までをコピペしてwgetしてみたのですが、どうやらその後の文字列も付け加えないといけないようです。リファラやユーザーエージェントは偽装しなくてもいけました。拡張子のあとの文字列はURLエンコードで変換されているので、sedで置換しています。間違っても動画を見て痴漢しないでくださいね。Yes 置換,No 痴漢 の精神で。

なお、動画をダウンロードする際は、いわゆる違法ダウンロードとならないよう、著作権法を守って楽しんでくださいね♡ また、本エントリーに書かれた方法は 2014/10/22 現在動作確認をとっていますが、xvideos側がシェル芸対策を施せば使えなくなる技でもあることをお含みおきくださいΞ(´ ゚_。`)

みなさんおはようございます。ゆうべ悶々としておりましたらこんな閃きが降臨してしまいまして。

突然ですが、水原さな、かわいいですよね。そんな彼女の連番JPG画像を保存したいとするじゃないですか。で、URLの構造ですが、女優名のディレクトリの配下に1から10のディレクトリがあって、その中に「女優名-1.jpg」〜「女優名-12.jpg」のファイルがあるとしましょう。

http://www.example.com/EROGAZOU/sana_mizuhara/1/sana_mizuhara-1.jpg
http://www.example.com/EROGAZOU/sana_mizuhara/1/sana_mizuhara-2.jpg
・・・
http://www.example.com/EROGAZOU/sana_mizuhara/1/sana_mizuhara-12.jpg
・・・
http://www.example.com/EROGAZOU/sana_mizuhara/10/sana_mizuhara-1.jpg
http://www.example.com/EROGAZOU/sana_mizuhara/10/sana_mizuhara-2.jpg
・・・
http://www.example.com/EROGAZOU/sana_mizuhara/10/sana_mizuhara-12.jpg

ディレクトリ名の数字もファイル名の数字もゼロパディングされていないので、seqコマンドを使わずにfor文でまわしてwgetできそうですね。しかし、画像を取得するときにディレクトリ別に保存しないと、ファイル名が重なってしまうので「女優名-1.jpg」「女優名-1.jpg.1」などのように嫌なことになってしまいます。というわけで以下のワンライナーです。

[ (っ´∀`)っ@友の会 ~]$ for A in {1..10}; do for B in {1..12} ; do mkdir -p ${A} ; cd ${A} ; wget http://www.example.com/EROGAZOU/sana_mizuhara/${A}/sana_mizuhara-${B}.jpg; cd ../ ; done ; done

さて次に、これらの画像URL一覧をテキストファイルで入手したとしましょう。テキストのファイル名は「LIST-jpg.txt」とします。この場合、ディレクトリ名の連番だけ意識すればよいのですが、ディレクトリ名の数字だけうまく抜き出したいですよね?幸いなことに、最下層のディレクトリが連番の数字となっています。そこでbasenameとdirnameの合わせ技です。大変満足、お見事、技有り一本!!

[ (っ´∀`)っ@友の会 ~]$ for A in $(cat LIST-jpg.txt); do mkdir -p $(basename $(dirname $A)) ; cd $(basename $(dirname $A)) ; wget $A ; cd ../ ; done

ね、簡単でしょう?

Twitterのタイムラインを眺めていたらこんなお悩みの方がいらっしゃいました。

というわけで、シェル芸でやってみることに。フォルダ構成はこんな感じにしました。

[nullpopopo@u24e tmp]$ find $(pwd) -type f | sort -n
/home/nullpopopo/tmp/1/1/wordpress.jpg
/home/nullpopopo/tmp/1/2/wordpress.jpg
/home/nullpopopo/tmp/1/3/wordpress_thumb.jpg
/home/nullpopopo/tmp/1/4/wordpress.jpg
/home/nullpopopo/tmp/1/5/wordpress.jpg
/home/nullpopopo/tmp/1/wordpress.jpg
/home/nullpopopo/tmp/2/1/wordpress.jpg
/home/nullpopopo/tmp/2/2/wordpress.jpg
/home/nullpopopo/tmp/2/3/wordpress_thumb.jpg
/home/nullpopopo/tmp/2/4/wordpress.jpg
/home/nullpopopo/tmp/2/5/wordpress.jpg
/home/nullpopopo/tmp/2/wordpress.jpg
/home/nullpopopo/tmp/3/1/wordpress.jpg
/home/nullpopopo/tmp/3/2/wordpress.jpg
/home/nullpopopo/tmp/3/3/wordpress_thumb.jpg
/home/nullpopopo/tmp/3/4/wordpress.jpg
/home/nullpopopo/tmp/3/5/wordpress.jpg
/home/nullpopopo/tmp/3/wordpress_thumb.jpg
/home/nullpopopo/tmp/4/1/wordpress.jpg
/home/nullpopopo/tmp/4/2/wordpress.jpg
/home/nullpopopo/tmp/4/3/wordpress_thumb.jpg
/home/nullpopopo/tmp/4/4/wordpress.jpg
/home/nullpopopo/tmp/4/5/wordpress.jpg
/home/nullpopopo/tmp/4/wordpress.jpg
/home/nullpopopo/tmp/5/1/wordpress.jpg
/home/nullpopopo/tmp/5/2/wordpress.jpg
/home/nullpopopo/tmp/5/3/wordpress_thumb.jpg
/home/nullpopopo/tmp/5/4/wordpress.jpg
/home/nullpopopo/tmp/5/5/wordpress.jpg
/home/nullpopopo/tmp/5/wordpress.jpg

一撃で消すなら以下のワンライナーで。

[nullpopopo@u24e tmp]$ find $(pwd) -name '*.[jJpPgG][pPnNiI][gGfF]' | egrep -v '(_thumb)' | xargs rm -f

それでは確認してみましょう。

[nullpopopo@u24e tmp]$ find $(pwd) -name '*.[jJpPgG][pPnNiI][gGfF]'
/home/nullpopopo/tmp/1/3/wordpress_thumb.jpg
/home/nullpopopo/tmp/5/3/wordpress_thumb.jpg
/home/nullpopopo/tmp/2/3/wordpress_thumb.jpg
/home/nullpopopo/tmp/4/3/wordpress_thumb.jpg
/home/nullpopopo/tmp/3/wordpress_thumb.jpg
/home/nullpopopo/tmp/3/3/wordpress_thumb.jpg

現場からは以上です。

※ 2014/05/29 14:45追記

[amazonjs asin="4904807073" locale="JP" title="USP MAGAZINE vol.13"]

久しぶりの勉強会ネタです。ここ最近いろんなつらみが重なって参加できてませんでしたが、「第10回記念シェル芸勉強会@シェルリアンタワー&第28回場所が未定だったが決まったぞ定例会」にUSP友の会スタッフとして参加してきました。しかも今回は日本UNIXユーザ会の後援つきでございます。いつもはKDDI ウェブコミュニケーションズ様に会場提供いただいていましたが、今回はGMOインターネット様のご好意により、勝手にセルリアンタワーをシェルリアンタワー呼ばわりしての開催です。ありがとうございま.sh。

今回、上田さん曰く「いつもより簡単です」とのことでしたが、やっぱり参加者を殺しにかかってきています。(;´д`) 問題と回答はこちらになります。

全8問のシェル芸問題を解いています。皆さん真剣です。

20140405_ShellGei10-001

シンガーソングライターみたいですが講師の上田先生です。

20140405_ShellGei10-002

GMOインターネット様による、VPS「ConoHa」宣伝タイムです。3000円分のクーポンもいただいたので、いろいろ遊んでみようと思います。なお、このプレゼンはパワポではなくlessで実演しています!

20140405_ShellGei10-003

6問目、hogeと書かれたファイルとhugeと書かれたファイルをそれぞれ別のディレクトリに振り分けるというエクストリームなシェル芸です。

20140405_ShellGei10-004

みんな大好きxargs。

20140405_ShellGei10-005

grep -o で縦に!

20140405_ShellGei10-006

ConoHaたんマジConoHa!

20140405_ShellGei10-007

当日の様子はこちらで振り返ることができます。

第10回記念シェル芸勉強会@シェルリアンタワー&第28回場所が未定だったが決まったぞ定例会 - Togetterまとめ

Ustream.tv (1)

Ustream.tv (2)

今回、2つ目から鱗だったのは「grep -o」の存在と、awkの「 awk '$1 != $2'」でした。(後者のawkは、USPマガジン Vol.12でさいとうさんが触れています)

grep -o の使いドコロはこんな感じですね。

もう少し詳しくフォローしますと、grepのhelpでは「-o, --only-matching       show only the part of a line matching PATTERN」と出てきます。つまり、パターンにマッチした箇所だけ出力してくれます。上田さんのブログにもサンプルがありますので見てみるとよいですよ。つまり

[hamada@localhost ~]$ echo hoge | grep -o .
h
o
g
e

こうなります。Q2のように「スペースと数字と改行を使って次のようなファイルを作り、書いた数を足し算してください」と言われても・・・

$ cat nums 
        1

2 3          
         4            5
        6    7

8      9

一旦 grep -o を使って整形してやればできました。 grep -o マジ grep -o !

[hamada@localhost ~]$ expr $(cat nums | grep -o . | xargs | sed -e 's/ / + /g')
45

awk '$1 != $2' が生きたのはQ7でした。「file1 file2」の行と「file2 file1」の行は重複とみなすという、そら恐ろしい条件で涙目になりましたが、さいとうさんのヒントでこんな解き方でできました。

[hamada@localhost ~]$ for i in $(seq 1 9); do for j in $(seq $i 9); do echo file$i file$j; done; done | awk '$1 != $2'

まだまだsh行が足りないですが、この2つを覚えただけでもかなり捗りそうです。次回、6月に大阪で、8月はOSCでシェル芸勉強会を開催する予定なので、みんなも来るといいよ!

最後におまけ。

 

[amazonjs asin="4904807065" locale="JP" title="USP MAGAZINE vol.12"]