ふるつき

私は素直に思ったことを書いてるけど、上から目線だって言われる

シェル芸でうんこつるんする

いわゆるとこのズンドコきよしです。

シェル芸botに食わせたんだけどうまく行かなくて悔しかったのでこっちに書いて溜飲を下げることにします。

やること

「う」「ん」「こ」の三文字のうちどれか一文字をランダムに流し続け*1、たまたま「うんこ」の順番で流れてきたときに、「つるん」します。

どのようにそのシェル芸を組み立てるかという話をね、していきます。

「う」「ん」「こ」を流す。

まずは無限ストリームを作りたいですね。こういうときは yes です。一文字ずつ区切って使うことを考えると yes う ん こ と空白区切りで出力してやるのが無難です。

ここまでのスクリプト

> yes う ん こ
う ん こ
う ん こ
う ん こ
う ん こ
う ん こ
う ん こ
う ん こ
う ん こ
う ん こ
う ん こ
う ん こ
う ん こ
う ん こ
う ん こ
う ん こ
...

一文字だけランダムに選ぶ

awk でやるのが良さそうだったんですが、 randの使いやすさから perl で行きます。

-nle オプションはシェル芸人御用達で、 -n 一行ずつ処理 。 -l 改行する。 -e コマンドラインスクリプトを指定。です

-a がつくと awk モードになって $F が使えます。 $F は入力をsplitしたやつで、標準入力が 「う ん こ」だったら ('う', 'ん', 'こ') になっていることが期待できます。 というわけで配列からランダムに一つ引っ張ってきますので perl -anle 'print $F[int(rand(3))]' になりそうです。ちなみにオプション引数の順番は気をつけたほうがいいらしい。

ここまで

> yes う ん こ | perl -anle 'print $F[int(rand(3))]'
ん
う
う
う
ん
う
こ
う
こ
ん
ん
こ
ん
...

うんこ判定

perlでいきます。 -n オプションがあると行毎に処理することになりますが、 BEGIN{} END{} があるとコンテキストを持てます。 というわけで起動時に配列を作っておき一文字ずつ先頭に追加。splice で消し飛ばしつつ直近3文字を保持します。

そして、 join で結合したものが こんう と一致したら直近3つが「うんこ」になっているので、 exit してperlを終了します。いい感じだ。もちろん入力は吐き直さないとだめなので print $_ はします。

ここまで

> yes う ん こ | perl -anle 'print $F[int(rand(3))]' | perl -nle 'BEGIN{@a=()} unshift(@a,$_); splice(@a,3); print $_; if (join("", @a) eq "こんう"){ exit();} ' 
ん
う
う
こ
う
ん
こ

「つるん」する

echo つるん

> yes う ん こ | perl -anle 'print $F[int(rand(3))]' | perl -nle 'BEGIN{@a=()} unshift(@a,$_); splice(@a,3); print $_; if (join("", @a) eq "こんう"){ exit();} ' ; echo つるん
う
う
ん
こ
つるん

見栄えがわるい

つるんだけ横になっていて気持ち悪いので、うんこまでの道のりもちゃんとヨコ読みにしてあげます tr -d '\n' で改行文字を消し飛ばせるのは常識ですね。

> yes う ん こ | perl -anle 'print $F[int(rand(3))]' | perl -nle 'BEGIN{@a=()} unshift(@a,$_); splice(@a,3); print $_; if (join("", @a) eq "こんう"){ exit();} ' | tr -d '\n'; echo 'つるん'
ここうこんこううこうここうんんうんうこうんうこうここううんこつるん

あー、スッキリ……!

perl に触るのなんて初めてなので苦労しました。

追記

うんこシェル芸で右に出るものはいないと噂の @grethlen さんがすごいきれいに出してた。シェル芸って感じですねすごい

*1:流すとかトイレですね。だれうま