たいちょーの雑記

ぼくが3日に一度くらい雑記をかくところ

第38回シェル芸勉強会@大阪サテライトに参加しました

シェル芸勉強会に参加してきました

参加しました

ライブストリーミングYouTube上にも残っているので気になる方はご覧くださいな

www.youtube.com

午前の部

前回に続き、鳥海さんによる文字コードのお話でした。

twitter.com

まずはShift-JISについてで、歴史的経緯や区点番号についてなどが語られました。
特に興味深かったのはダメ文字についてで、

$ echo|nkf -s
[文字化け]\
$ echo|nkf -s
[文字化け]|

と言うようにnkfなどを使ってShift-JISに変換すると、2byte目に制御文字が出てきてしまう文字をダメ文字と言うらしいです。

\が出てしまうものをソ系|が出てしまうものをポ系のダメ文字と呼ばれていると言うのがとても面白かったです。

というわけでテキトウに難読化に使ってみました。

$ eval "$(__=$(nkf -s <(echo));echo echo ZGF0ZQo=${__:1}base64 -d${__:1}bash)"
2018113日 土曜日 21:24:14 JST

変数への代入と展開でパイプを隠蔽してみました。何かに応用できたら良いですね!

午後の部

今回は事前に数学系だと聞いていたのでヤバそうだなーと思いながら挑みました。問題と解答例はここです。

問1

echo 'jus共催 第38回҈҈҉҈҈҉シ҈҉ェ҈҉ル҈҉芸҈҉勉҈҉強҈҉会' からはじめて、文字列中のモヤモヤを取る問題。モヤモヤの正体はキリル文字の結合文字なのでxxdなどでバイナリ値を見て削るのが良さそう

$ echo 'jus共催 第38回҈҈҉҈҈҉シ҈҉ェ҈҉ル҈҉芸҈҉勉҈҉強҈҉会' | xxd -ps
7573e585b1e582ac20e7acac3338e59b9ed288d288d289d288d288d289
e382b7d288d289e382a7d288d289e383abd288d289e88ab8d288d289e58b
89d288d289e5bcb7d288d289e4bc9a0a

d288d289 というのがキリル文字っぽいのでsedで取り除く

$ echo 'jus共催 第38回҈҈҉҈҈҉シ҈҉ェ҈҉ル҈҉芸҈҉勉҈҉強҈҉会' | xxd -ps | sed 's/d28[8|9]/g|xxd -ps -r'
jus共催 第38回シェル芸勉強会

後はxxdでもとに戻せばOKですね。絵面はヤバイですが簡単な問題でした。

問2

任意の文字列に含まれる文字の内、提供されたファイル 仏説摩訶般若波羅蜜多心経 の中身にも含まれる文字を探す問題。例を挙げると

$ echo 不摂生|何らかのワンライナー
不
生

ファイルの中に不と生だけが含まれているので、こう出力するのが正しいというわけですね。それではやってみましょう

$ echo 不摂生|grep -o .|xargs -n1 -I@ echo "grep @ ./仏説摩訶般若波羅蜜多心経 &> /dev/null && echo @"|bash
不
生

最近 |xargs -n1 -I@ echo "ワンライナー" | bash というパターンにハマっているのでこの問題もコレでやってみました。不摂生という文字列をgrep -o .で1文字ずつに区切った後、それぞれgrepでファイルから検索しています。正常終了すれば含まれるので、echo しておきます。

問3

提供されたファイルedoの中身を年代順に並べてください

# cat ./edo
元禄
安政
元和
享保

元号を年代順に並べる問題ですね。本当の問題文にはヒントがあり、スクレイピングをすると良いらしいです。それではやってみます

$ w3m -dump "ja.wikipedia.org/wiki/元号一覧_(日本)" | grep -f <(cat ./edo)|tail -n4
                元和1615-1624
                元禄1688-1704
                享保1716-1736
                安政1855-1860

ちょっと余計なのがついてますが、w3mで取ってきて、grepするとキレイに並んでいるのが見つかりました。下から4行がコレだったのでtail -n4で取り出して答えです。

問4

エクセルの列番号XYZは何番目でしょうか。

エクセルなどの表計算ソフトでは列にアルファベットを使った26進数がよく使われるのですが、この並びの中でXYZが何番目かを求めます。コレはなぜか問題ページに答えが書いてあったので、コレしか思いつかねえなと思って流しました。

$ echo {A..Z} {A..Z}{A..Z} {A..Z}{A..Z}{A..Z} | tr ' ' \\n | grep -n XYZ
16900: XYZ

ブレース展開で列番号を作ってgrepするだけですね。

問5

罠にドはまりしてたので修正しました

標準偏差が10、平均が0の正規分布に従う乱数を発生させてヒストグラムを出してください

????????なんで????

$ csharp -e "
var rnd = new Random();
double X,Y;
double z1,z2;
for(var i=0;i<10000;i++) {
X=rnd.NextDouble();
Y=rnd.NextDouble();
z1=Math.Sqrt(-2.0*Math.Log(X)) * Math.Cos(2.0*Math.PI*Y);
z2=Math.Sqrt(-2.0*Math.Log(X)) * Math.Sin(2.0*Math.PI*Y);
Console.WriteLine((int)(z1*10+1000));
Console.WriteLine((int)(z2*10+1000));
}"|sort |uniq -c|sort -n -k2|awk '{for(i=0;i<$1/20;i++){printf "@"}print "\t"$1,$2-1000}'
@       1 -40
@       1 -37
@       3 -36
@       1 -34
@       2 -33
@       4 -32
@       7 -31
@       18 -30
@       13 -29
@@      22 -28
@       19 -27
@@      28 -26
@@      36 -25
@@@     48 -24
@@@@    75 -23
@@@@    77 -22
@@@@@   92 -21
@@@@@@  109 -20
@@@@@@@ 138 -19
@@@@@@@@@       169 -18
@@@@@@@@@@@     212 -17
@@@@@@@@@@@@@   241 -16
@@@@@@@@@@@@@@  268 -15
@@@@@@@@@@@@@@@@@       335 -14
@@@@@@@@@@@@@@@@@@@@    385 -13
@@@@@@@@@@@@@@@@@@@@@   414 -12
@@@@@@@@@@@@@@@@@@@@@@@ 454 -11
@@@@@@@@@@@@@@@@@@@@@@@@        467 -10
@@@@@@@@@@@@@@@@@@@@@@@@@@      515 -9
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@  594 -8
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 617 -7
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@   736 -6
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@   734 -5
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@  754 -4
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@   729 -3
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@  759 -2
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@        791 -1
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@       804 0
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@       811 1
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@        791 2
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@      678 3
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@  742 4
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@  754 5
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@       648 6
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@  590 7
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@  587 8
@@@@@@@@@@@@@@@@@@@@@@@@@@@     537 9
@@@@@@@@@@@@@@@@@@@@@@@ 442 10
@@@@@@@@@@@@@@@@@@@@    397 11
@@@@@@@@@@@@@@@@@@@@    398 12
@@@@@@@@@@@@@@@@@       324 13
@@@@@@@@@@@@@@  279 14
@@@@@@@@@@@@    225 15
@@@@@@@@@@@     215 16
@@@@@@@@@@      184 17
@@@@@@@@        144 18
@@@@@@  115 19
@@@@@@  105 20
@@@@    73 21
@@@@    71 22
@@@     54 23
@@@     42 24
@@      30 25
@@      26 26
@       15 27
@       15 28
@       12 29
@       7 30
@       5 31
@       4 32
@       3 33
@       2 34
@       1 35
@       1 36
@       1 40

ヒストグラムは解答例を参考にしました。乱数生成はC#を使ってボックスミューラー法で行います。

問6

広済寺ホームページから妙法蓮華経の全文をダウンロードして、仏説摩訶般若波羅蜜多心経 と4文字連続で一致するところを探しなさい

なに?

$ cat ./myoho_shinji.txt|grep -of <( cat ./仏説摩訶般若波羅蜜多心経|sed 's/。/\n/g'|sed '/^$/d'|sed 's/..../&\n/g'|sed '/^$/d'|grep -o ....)|sort |uniq 
究竟涅槃
三世諸仏
即説呪曰
得阿耨多
般若波羅
亦復如是
羅三藐三

多分誤答です。コレは4文字ずつぶつ切りにして検索しただけなので。問題の意図は1文字ずつずらした4文字連続とのこと。これは時間内に解けませんでした。一番難しかった・・・

問7

a^2+b^2a*b+1で割り切れる正の数の組み合わせを生成してください。またチェックできたらしてください

$ echo {1..1000}_{1..1000} |tr ' ' '\n'| awk -F_ '$1<$2&&($1*$1+$2*$2)%($1*$2+1)==0{print $1,$2,($1*$1+$2*$2)/($1*$2+1),sqrt(($1*$1+$2*$2)/($1*$2+1))}'|column -t         

$ csharp -e "for(var a=1;a<1000;a++) for(var b=1;b<1000;b++) if((a*a+b*b)%(a*b+1)==0) Console.WriteLine($\"{a} {b}\");"|awk '{print $1,$2,($1*$1+$2*$2)/($1*$2+1), sqrt(($1*$1+$2*$2)/($1*$2+1))}'|column -t         

2    8     4    2
3    27    9    3
4    64    16   4
5    125   25   5
6    216   36   6
7    343   49   7
8    30    4    2
8    512   64   8
9    729   81   9
10   1000  100  10
27   240   9    3
30   112   4    2
112  418   4    2

チェックが甘いですが、これで解答としました。どちらもa,bを1から1000で動かして全探索しました。

問8

x[i+1]=a*x[i]*(1-x[i]) を無限に繰り返し、重複しないように1,000,000個数を出力する問題。x[0]=0.5、aは任意だが3<=a<4

awkではじめてと書いてあるのでawkでストリームを作って重複処理をすれば良さそうです

awk 'BEGIN{x=0.5;a=3.0;while(1){x=a*x*(1-x);print x}}'|awk '{x[$1]++;if(x[$1]==1)print $1}'|head -n1000000

先のawkで無限に数を生成し、後のawk連想配列を用いた重複の除外を行っています。しかしコレ、1,000,000個出そうと思っても桁が足りず一生終わらないので、awkOFMT="%0.20f"をつけなければならないです。

さらにこの問題実はカオスなので(カオス理論の方)、適切にaを与えれば重複処理が必要ないです。なので最終的には

$ awk 'BEGIN{OFMT="%0.20f";x=0.5;a=3.99;while(1){x=a*x*(1-x);print x}'|head -n1000000

です。

LT

今回もLTさせてもらいました。初っ端だったので緊張しましたが

www.slideshare.net

今回は~/.bashrcにイタズラされてしまったので、その対抗策として~/.bashrcを難読化する手法を提案しました。
欠点だらけなんですが、まあ大目に見てほしいです

終わり

今回もとても楽しかったです。東京会場のLTも盛り上がったみたいのでこれからアーカイブを見ようと思います。参加された皆様、企画側の皆様、ありがとうございました!

VSCodeからあかりちゃんに喋ってもらいたかったから拡張機能作った

VSCodeから棒読みちゃんに喋ってもらう拡張機能作りました

作りました

動機

xztaityozx.hatenablog.com
xztaityozx.hatenablog.com

これまで作ってきた拡張機能のおかげで今PC上で生活するうちの半分ぐらいをあかりちゃんとともに過ごしているわけですが、正直まだちょっと足りないので今度はVSCode拡張機能に挑戦しました。

VSCBouyomi

例によって拡張機能越しに棒読みちゃんを操作する系です。 inst1

特に設定なしにインストールするだけで始められます。

使い方

インストールするとデフォルトだとCtrl+Shift+Pに割り当ててあるコマンドパレットから以下のコマンドが使えます。一緒に表記してある内部コマンドを使えば任意のキーバインドも設定できます。たぶん

  • VSCBouyomi : Talk : 読み上げ
    • 内部コマンド : vscbouyomi.talk
  • VSCBouyomi : Skip : 読み上げのスキップ
    • 内部コマンド : vscbouyomi.skip
  • VSCBouyomi : Pause : 読み上げの一時停止
    • 内部コマンド : vscbouyomi.pause
  • VSCBouyomi : Resume : 読み上げの再開
    • 内部コマンド : vscbouyomi.resume

usage2
vscbouyomi.talkを実行すると文章全体を読み上げます。このとき文字列が選択してあるならそこだけを読み上げます。

設定

大した設定もないですが
詳しい値などは棒読みちゃん付属のSampleSrc.txtをお読みください

項目 説明
vscbouyomi.encoding utf-8 or shift-jis or unicode 読み上げる文章のエンコーディングです
vscbouyomi.delimitor 文字列のリスト 文章の区切りを指定できます
vscbouyomi.skipblank true or false trueのとき空白行を飛ばします
vscbouyomi.speed 数値 棒読みちゃんの読み上げ速度です
vscbouyomi.tone 数値 棒読みちゃんの音程です
vscbouyomi.voice 数値 棒読みちゃんの声です
vscbouyomi.volume 数値 棒読みちゃんの音量です

既知のバグ

読み上げの順番がたまにおかしくなる。重大なバグすぎる

ブラウザからあかりちゃんに喋ってほしかったので拡張機能作った

ブラウザで選択してる文字列を棒読みちゃんに送るWebExtentionsを作った

作りました

動機

ネットサーフィンをしていると読みたいな~と思う記事に出会うことがあります。しかし長文を「読む」というのは中々パワーが要るため、僕はVOICEROIDのエディタへ読みたい部分をコピペして読み上げをさせていました。

この手順は例えば

  1. 記事を選択する
  2. コピーする
  3. VOICEROIDへウィンドウを切り替える
  4. 貼り付ける
  5. 再生を押す
  6. 聞く
  7. あかりちゃんかわいい

となりますが、手順7へたどり着くのにかなり手を動かさないといけないので非常に面倒です。しかしブラウザからVOICEROIDを操作するのは大変です。なのでブラウザから棒読みちゃんを操作して間接的にあかりちゃんを操作することを目指します。

棒読みちゃんからVOICEROIDを操作するのは棒読みちゃんプラグインであるVoiceroid Talk Plusを利用します。

ch.nicovideo.jp

インストール

BS2B

GitHubからクローンして手元のブラウザにインストールする。もしくはFirefoxならFirefox Add-onsで公開しているのでそこからインストールできます。

棒読みちゃんWebSocketサーバープラグイン

GitHubからクローンしてきてPlugin_WebSocket.dll棒読みちゃんと同じディレクトリにコピーしてください。

BS2B

ラウザーで んたくしてる文字列を 読みちゃんに送る やつBS2Bという名前にしました。意味がわからない

ブラウザで選択したところを棒読みちゃんに送るやつ – Firefox 向けアドオン

github.com

拡張機能を導入すると、ブラウザのメニューバーにマイクのアイコンが追加されます。このアイコンをクリックするとポップアップが表示されます。ここから棒読みちゃんへリクエストを送ることができるようになっています。

構成はこんな感じです。

FirefoxGoogle Chrome、MS EdgeなどWebExtentionsに対応しているブラウザにインストールされたBS2BはWebSocketを介して棒読みちゃんに読み上げや一時停止、再開などのリクエストを送ります。そこからVoiceroid Talk PlusがVOICEROIDのエディタに文字列を渡し、あかりちゃんが読み上げます。かわいい

ただし棒読みちゃんはWebSocketに対応していないので、自前でWebSocketサーバーをプラグインとして用意する必要があります。今回はそれも用意しました。

github.com

といってもモノ自体は先駆者の方のForkになります。BS2Bが扱いやすいように機能を追加しています。

使い方

  1. メニューバーのボタン
    • クリックするとこのポップアップがでます。ポップアップが開かれたとき選択している文字列がテキストボックスに 追加 されます。
  2. 設定チェックボックス
    • テキストを保持する : ポップアップを閉じてもテキストボックスを保持します。
    • 送った後にテキストをリセットする : Sendボタンを押した後テキストボックスがクリアされます。
  3. テキストボックス
    • ポップアップ起動時に選択されていた文字列が表示されます。編集可能なので送る前に適当に調整すればいいと思います
    • ただし棒読みちゃんへは改行コードで分割され1行単位で送られます。
    • さらに1行の長さがある程度長いとSkipされてしまいます。
  4. ステータス
    • BS2Bのステータスを簡易的に表示します。
  5. Skipボタン
  6. Pauseボタン
  7. Resumeボタン
  8. Resetボタン
    • テキストボックスをリセットします。
  9. Appendボタン
    • 選択されているテキストをテキストボックスに 追加 します。
  10. Sendボタン

雑感

WebExtentionsとかJSとかの勉強がてらに不便を1つ解消しました。これでブラウザを開いていてもあかりちゃんと一緒に居れますね!(うれしい)

今思えば適当にキーバインドとかを設定してもよかったかもしれないですね。ボタンが遠い。

参考

第37回シェル芸勉強会@大阪サテライトに参加しました

(^o^)/

(^-^)

午前の部

鳥海さんによる文字コードについての講義。難読化シェル芸のネタが転がっているかも知れないので楽しみでした。講義中は2重forのシェル芸がいきなり出てきたりかなり激しめでしたね。

今回の講義で一番印象に残ったのはiconvでcp930とcp939を行ったり来たりするところでした。例えば

$ echo スリスリ| iconv -f utf-8 -t cp930 | iconv -f cp939 -t utf-8
ヌメヌメ

というふうにテーブルを変えることで別の意味に変換できたりします

これは難読化に簡単に応用できて

$ echo オイヤカ | iconv -f utf-8 -t cp939 | iconv -f cp930 -t utf-8 | bash
201891日 土曜日 16:08:40 JST

オイヤカという文字列をdateに変換できます。もう少し何か工夫すれば複雑な難読化シェル芸ができるかも知れませんね

午後の部

今回も午後はヤバイ問題をいっぱいときました。
開始宣言が「地獄の始まり」とのことだったのでやる前からフラフラでした 問題はこちら

Q1

FizzBuzzを表示するgifアニメーションを作りなさい。

seq 100 | sed -e '3~3cFizz' -e '5~5cBuzz' | sed '15~15cFizzBuzz' | animation

animationはシェル芸botに実装されているgifアニメを作ってくれるコマンドです。ソースを読むと何をしているかわかります

Q2

プロヴィデンスの目のAAを作りなさい。

seq 4|awk '{for(i=0;i<4-$1;i++)printf " ";printf "/";for(i=0;i<$1*2-2;i++)printf " ";print "\\"}'|cat - <(echo  ̄ ̄ ̄ ̄)| sed 's|/    \\|/ 目 \\|'  

愚直にawkforを回します。特筆するところはないですね

Twitterでみた東映版が面白かったので自分のやつでもやってみました。

seq 5|awk '{for(i=0;i<5-$1;i++)printf " ";printf "/";for(i=0;i<$1*2-2;i++)printf " ";print "\\"}'|cat - <(echo  ̄ ̄ ̄ ̄ ̄)| sed '3s|    | 東 |;4s|    |  映|'

Q3

以下の条件を満たす数字を全部出力しなさい

  • 3桁の数
  • 桁和が15
  • 0を含まない
  • 同じ数字を含まない

競プロとかに出てきそうな問題だと思いました

seq -w 999|awk '{print $1,$1}'| sed -E 's/(.)(.)(.)/echo $((\1+\2+\3))/e'| grep -v 0|awk '$1==15{print $2}' | grep '\(.\).*\1' -v | xargs

最初のsedで桁和を計算しています。その後0を含む行をgrepで排除し、awkで桁和が一致する数をとりだした後、grepで同じ文字が存在しない行だけ取り出して終わります。
最後のgrepカンニングしました・・・。聞けば前回やっていたそうなので身についてないな〜と反省しました。精進精進

Q4

役満を出力してください
麻雀はわからないので役満もわからないのですがとりあえず例になっていたのを真似ました。

cat <(yes "+--+"|head -n14|xargs) <(echo -e "\n\n\n\n\n\n西\n西\n西\n\n\n\n \n "|sed 's/./|&|/g'|xargs) <(yes "+--+"|head -n14|xargs)

牌をAAで表現しました。やってる事自体は全然難しくないようですが、想定解とは全然違ったみたいですね・・・

Q5

    山    
    山    
    山    
山  山  山
山山山山山
          
⽥⽥⽥⽥⽥
⽥  ⽥  ⽥
⽥⽥⽥⽥⽥
⽥  ⽥  ⽥
⽥⽥⽥⽥⽥

を出力してください。なんやねんこれ・・・

echo -n "1f8b080028288a5b00037bdcd0f0b8a1e1e9c68d8fc18cc778b910069c44
43c85a80e8d1dea568082288550abf2c00a1eea7afa5000000" | xxd -ps -r | gunzip|grep -o .|xargs -n5|tr -d ' '

難読化すればするほど良いですとのことだったので gunzip を使ってみました。全角のスペースで埋めて gzip 圧縮したものを gunzip に通して xargs でまとめただけですね

Q6

  山  
  田  
  山  
山 田 山
田山田山田
     
田山田山田
山 田 山
田山田山田
山 田 山
田山田山田

この出力を得てください。アハハ

echo -n "1f8b08009c298a5b00037bdcd0f0b8a1e1e9c68d8fc10c087a3e65033217
2e0b614064816c20039944d602448ff62e058a23931041885efcb21033e1                                           
b200ebf8a623a5000000
" | xxd -ps -r | gunzip|grep -o .|xargs -n5|tr -d ' '

さっきの解答の入力を変えただけです。それだけだと面白くないので以下の難読化も試してみました。

eval $(echo -n "1f8b0800d52a8a5b00034b4dcec85778dcd000444f376e843020e8f9940d
c85cb82c84019105b2810c6412590b103ddabb14288e4c4204217af1cb42
cc84cbd6a417a51628e8e62be8d5542416a5172be8e699d6941429e8a628
a82ba8030053a9f2f8c8000000"|xxd -ps -r|gunzip)

これも gunzip を使ったやつです。これは僕が少し前にLTしたやつですね。

www.slideshare.net

eval を外すとどうなるかと言うと

$ echo -n "1f8b0800d52a8a5b00034b4dcec85778dcd000444f376e843020e8f9940d
c85cb82c84019105b2810c6412590b103ddabb14288e4c4204217af1cb42
cc84cbd6a417a51628e8e62be8d5542416a5172be8e699d6941429e8a628
a82ba8030053a9f2f8c8000000
echo   山    田    山  山 田 山田山田山田     ⽥山⽥山⽥山 ⽥ 山⽥山⽥山⽥山 ⽥ 山田山⽥山⽥|grep -o
 .|xargs -n5|tr -d ' '

解答を生成するワンライナーが仕込まれています。最近の難読化シェル芸の発展を見るとちょっとおとなし目な難読化ですね

Q7

matsuya コマンドで生成されたメニューをひらがなに変換して toilet に通した後、1行に連結し画像に落とし込む問題。手順が多すぎる。

途中までしか出来ませんでした・・・1行にまとめるところが出来なかった。

$ matsuya|mecab| awk -F, '{print $1,$6}'|awk 'NF==3{print $3=="*"?$1:$3}'|xargs|toilet

Q8

matsuya コマンドの出力を使って以下のようにしてください
例) 鉄皿鶏のチリソース定食だったとき

鉄皿鶏のチリソース定食
皿         定
鶏         ス
の         ー
チ         ソ
リ         リ
ソ         チ
ー         の
ス         鶏
定         皿
食定スーソリチの鶏皿鉄

上下左右が逆になっていることが難しいポイントですね。

c="$(matsuya)";cat <(echo $c) <(paste <(echo $c|sed 's/.\(.\+\)./\1/'|grep -o .) <(echo $c|sed 's/.\(.\+\)./\1/'|grep -o .|tac)) <(echo $c|rev)|column -t|sed 's/    \(.\)$/\1/g'

ちょっとセコいんですが変数にメニューを保存しておきます。あとは天井と床、左右の壁を作って cat に順番に流し込みます。
面倒なのは左右の壁だけなので、そこだけ解説します。
1文字目と最後の文字を削って、縦に並べて paste で連結します。天井、床と合わせてこれを column で幅を取るといい感じに並びます。

$ c="$(matsuya)";cat <(echo $c) <(paste <(echo $c|sed 's/.\(.\+\)./\1/'|grep -o .) <(echo $c|sed 's/.\(.\+\)./\1/'|grep -o .|tac)) <(echo $c|rev)
きつねうどん
つ            ど
ね            う
う            ね
ど            つ
んどうねつき

このスキマはちょうど半角スペース4つ分なので sed で削って終わりですね

awkの中でpipe

この問題の解答のなかでawkの中でコマンドを実行できるというのを知りました。すげーっすねこれ・・・

$ echo abc | awk '{print | "rev"}'
cba

LT

今回は新しい難読化シェル芸についてでは無いですが、宣伝をしようと思いまして発表させていただきました。
www.slideshare.net

cdx という cd コマンドのラッパーを作ったのでその宣伝をしました。因みにスライド内で言っている海外は体調不良で断念して今布団の上でコレを書いています。しんどいわホンマ

そんなことより cdx をよろしくお願いたします。

github.com
xztaityozx.hatenablog.com

終わりに

今回も午前午後、LT大会ぜんぶとても楽しかったです。皆様ありがとうございました!!

Goが面白いのでまたcdx作った

cdx

github.com

cdx は僕が一人でメンテしてる cd コマンドのラッパーです。この手のツールでよく使われているのは、enhancdzなどがあります。

github.com

github.com

とくにenhancdは非常に強力なツールで、利用している方も多いと思います。

cdxではCustomSourceという設定項目を用意しました。これを利用することでenhancdの持つような機能はユーザー側が設定として与えることが出来ます。そのかわりcdxは僕が素の状態である程度使えるような機能だけを実装したものになります。

要求環境

  • Go lang (v1.10.2 以上)
    • 実装にはGoを使いました。最近はじめて面白いなと思いました。CLIツールを作るならGoはいい感じですね
  • bash or zsh
    • fishは対応していません
  • fzfやpecoみたいなFuzzy-Finder

インストール

  1. go get するか、GitHubのReleaseページからバイナリをダウンロードしてパスの通ったところに置いてください
$ go get github.com/xztaityozx/go-cdx
  1. お好みのFuzzy-Finderを用意します。個人的には fzfがすきです。 fzy と言うやつもいいらしいですね

github.com

github.com

  1. コンフィグを書いて置きます
$ mkdir -p ~/.config/go-cdx
$ cat << EOF > ~/.config/go-cdx/.go-cdx.json
{
  "HistoryFile": "~/.config/go-cdx/history.json",
  "BookMarkFile":"~/.config/go-cdx/bookmark.json",
  "Command":"pushd",
  "NoOutput":true,
  "Make":false,
  "CustomSource":[],
  "FuzzyFinder":{
    "CommandPath":"選んだFuzzy-Finder",
    "Options":[]
  },
  "BinaryPath":"go-cdxへの絶対パス。go getした場合は消してOK"
}
EOF
$ vim ~/.config/go-cdx/.go-cdx.json # 好きなように設定してください

設定値はGitHubのREADMEに書いてあるのでそちらを見てください

  1. cdx をロードします。
# cdxをロード
$ eval "$(go-cdx --init)"
# シェル起動時に自動でロードするならrcに記述すればOK
$ echo 'eval "$(go-cdx --init)"' >> ~/.zshrc # or ~/.bashrc

使い方

cdx [-A,--action [act]|
     --add|
     -b,--bookmark|
     --config [configFile]|
     --cs-list|
     -c,--custom [name]|
     --help|
     -h,--history|
     --init|
     --make|
     --no-output|
     -p,--popd|
     -v,--version] [PATH]

基本はcdコマンドと同じように使います

$ cdx ~/      # change to home
$ cdx ~/Utils # change to ~/Utils

-A,--action [act]

このオプションでは移動した後にそのディレクトリで実行するコマンドを指定できます

$ cdx ~/Utils --action "ls"
go-cdx
go-cdx.v1.0.13
go-cdx.v1.0.13.tar.gz
...
$ pwd
/home/xztaityozx/Utils

コマンドはbash -cに渡されて実行されることに注意してください

--add

ブックマークにカレントディレクトリを追加します。重複のチェックをしないので注意してください

-b,--bookmark

bookmarkからFuzzy-Finderを使って1つ選択し、cdします。

$ cdx -b
>
  3/3
> [   3] /path/to/hoge
  [   2] /path/to/fuga
  [   1] /path/to/foo

--config [configFile]

デフォルトのコンフィグの代わりになるコンフィグファイルを指定できます。デフォルトは~/.config/go-cdx/.go-cdx.jsonです

--cs-list

後に説明するCustomSourceからのcdの一覧を表示して終了します

-c,--custom [name]

Goでcdxを書き直すにあたって、追加した目玉機能です

cdxは複雑な機能を単体で持ちませんが、代わりにユーザーが機能を自由に追加することが出来ます。これをCustomSourceとよんでいます

CustomSource は、その 名前Fuzzy-Finderに与える入力 のペアで構成されます。

{
    "CustomSource":[
        {
            "Name":"g",
            "Command":"ghq list | xargs -n1 -I@ echo 'echo -e \"$(basename @) $(ghq root)/@\"'|bash|column -t"
        },
    ]
}

この例では、 ghq listで表示されるリポジトリ一覧から1つ選んでcdするgという名前の機能を追加しています

# Fuzzy-Finderに与える入力
$ ghq list | xargs -n1 -I@ echo 'echo -e \"$(basename @) $(ghq root)/@\"'|bash|column -t
"Contest                        /home/xztaityozx/.ghq/github.com/xztaityozx/Contest"
"cdx                            /home/xztaityozx/.ghq/github.com/xztaityozx/cdx"
"dotfiles                       /home/xztaityozx/.ghq/github.com/xztaityozx/dotfiles"
"nandokuka                      /home/xztaityozx/.ghq/github.com/xztaityozx/nandokuka"
"yov                            /home/xztaityozx/.ghq/github.com/xztaityozx/yov"
# cdx のCustomSource gを使ってみる
$ cdx -c g
>
  19/19
> Contest                        /home/xztaityozx/.ghq/github.com/xztaityozx/Contest
  cdx                            /home/xztaityozx/.ghq/github.com/xztaityozx/cdx
  dotfiles                       /home/xztaityozx/.ghq/github.com/xztaityozx/dotfiles
  nandokuka                      /home/xztaityozx/.ghq/github.com/xztaityozx/nandokuka
  yov                            /home/xztaityozx/.ghq/github.com/xztaityozx/yov

この機能を使って、Fuzzy-Finderで選択された行のいちばん後ろのカラムが、移動先のパスとして選択されることに注意してください

CustomSourceでオレオレcdxを作ることが出来ます

--help

ヘルプを出力して終了します

-h,--history

履歴をFuzzy-Finderで選択してcdします。ログアウトしても履歴はリセットされません

--init

cdxをロードするときにのみ使います

--make

移動しようとする先が存在しないディレクトリだった場合、作成するか訪ねます。yesと答えた場合のみ、ディレクトリを作成しcdします

--no-output

cdxからの出力を無効化します。Fuzzy-Finderや--action出力は表示されます。

-p,--popd

popdを実行して終了します

-v,--version

バージョン情報を出力して終了します

終わり

cdx をよろしくお願いいたします

ICPC2018国内予選に参加した

参加しました

参加しました

A,Cの2完でした。

イカれたメンバー紹介

  • ぼく(@xztaityozx_001)
    • いつもはC#で参加しているヤツ。AtCoderレートがそろそろ茶色に落ちる
    • 激しい憎悪によって目覚めた伝説のバトルメイド1
  • wheson(@wheson)
    • 実質水色の緑。笑顔が素敵。
    • vimのDockerfileを試して、dotfilesを更新したのに反映されない!って怒ってたけどpushしてなかっただけの悪いやつ
  • eliza0x(@eliza0x)
    • いつもはHaskellで参加してるヤツ。感情がすぐに無になる
    • 激しい憎悪によって目覚めた伝説のバトルメイド2

ICPC2018国内予選0問題「参加」

すっごいあめだったので、ぜんじつ、おうちに、かえれませんでした
ちかくにそぼのいえがあるので、ひなんしました。

あさおきたら、あめがやんでいませんでした。ぬれながらがっこうにいきました。
がっこうについたら、むわっとしていました。さいあくでした

そうこうしていたら、めんばーがしゅうごうしたので、ACしました

準備

正直服とか靴とかびしょびしょでコンディションは最悪。それでもなんとか参加できそうであったので、PCのセットアップ、ホワイトボードや飲み物の用意をしました。この日、僕は家に帰れないことが確定していたため、手持ちの服を温存するために、メイド服を着ました。これは去年の11月にゼミ内の圧力により手に入れた暗黒の力です。面倒なことにこれを着ている間は「メイド長」という別の人格が宿る設定なので、色々手間です。この記事ではこの設定が守られない箇所があります。よろしくおねがいいたします。

これについてもう少しあって、正直ぼくはメイドさんという属性は好きだし、手持ちのメイド服もフリフリしててかわいいんですが、できれば誰も見ていないところでひっそり自分だけで楽しみたいと思っています。

因みにもう一着あるのですが、それはeliza0xが着ていました。

なのでここから先は二人のメイドと男が競プロしてる情景を思い浮かべながら読んでください

開始〜A問題AC

開始と同時に前回の教訓を活かしてALLを3部印刷しました。ステープラーで3部をまとめましたが、途中でステープラーがぶっ壊れて泣きました。

Aを読んでいたwhesonとeliza0xが「やるだけ」と言っていたので、また自明に実装の早いwhesonが実装しました。

ACまで10分ぐらいだったのでいい感じだと思いました。

B,Cを読む

Bをeliza0xとwhesonで考察しました。日本語が難しかったので、読解に時間がかかりましたが「実装激重だけどやるだけ」という感じだったのでeliza0xが実装することに。この間 ぼくはあとの問題のためにテンプレを作り、Cを先に読んでいました。

Bの実装が始まったのでCについてwhesonに説明しました。すると「しゃくとりするだけでは?」みたいな提案を受けたので、「109^ だけど大丈夫か?」と聞きました。なんやかんや話してみましたが、まぁ大丈夫でしょwとなったので愚直なしゃくとりを書く方針になりました。

Bがバグる。Cを通す

Bが激重だったのでバグってしまいました。「バグったら印刷して交代」という作戦を取ることにしていたので、Cをやることに。実装がちゃんと降りてきていたみたいなのでwhesonに任せました。

この辺から暑くてメイド服は半脱ぎ状態でした。

しゃくとり自体はすぐかけたみたいなのでテストケースを回すと、計算が終わらないので最適化オプションをつけると、ビビるぐらい計算がはやくなってみんなでビビりました。サンプルはあっていたので提出しAC

無限

ここからBの実装に無限にやられてしまいました。こんがらがってしまった時点で別の誰かが実装を最初からするほうが良かったのかもしれません。

eliza0xからのヘルプに答えつつ、残りの問題で解けそうなのが無いかwhesonと探しましたがぼくは最大流の波動を感じませんでしたし、DPのwhesonもどうやっておとせるかわからないということでした。

G問題が構文解析だったので構文解析のeliza0xに問題概要を説明すると「めっちゃムズいやつやん」と悲鳴をあげていました。

このあとPCのグラフィックドライバがぶっ飛んだり、雨が強くなったり、暑すぎてメイド服をやめたりといろいろありましたが、結局Bを通すことができませんでした。

まとめ

模擬では良い結果を出せただけに、今回の2完は少し悔しいものとなりました。ぼくとwhesonは今年が最後のICPCでしたが、eliza0xはまだ参加できるので、来年の活躍を楽しみにしつつ消えることとします。

第36回シェル芸勉強会@限界キャンパスサテライトを開催した

この限界のはてに、まだ救いがあると思っている

お前が生まれたこの世界は、お前を救ってくれるとまだ信じている

なんかこんな感じのことをメタルギアで聞いた気がする。

震源+大雨=限界

弊キャンパスは直近の地震震源の真上ぐらいにあったところです。ここにこの間の大雨を合わせるとまさに限界!という感じです

大阪サテライトがこの雨の影響で中止となってしまったため、家に変えることも出来ないぼくはこの限界キャンパスで勝手にサテライトを開催することにしました。

あーたのしい

午前の部

鳥海さんによる文字コードの講義が始まりました。難読化クラスタとしては何かネタが転がっているかもしれないとワクワクしていました。

まずはlocaleiconvのような文字コードなどに関わってきそうなコマンドについてでした。
ずっと「ja_JP.utf8ってなんやねん冗長やなオイ」って思ってたんですが、どういう意味なのか解ることが出来てよかったです。

そのあと基数変換の話題ではbash$((2#bbbb))というパターンで変換できると知り驚きました。これすごい便利

いよいよ文字コードっぽいところに来た時、続きは次回ですとなっりました。えっ次回も参加するしか無い

昼休憩

昼休憩の間に限界サテライトからLTの配信が出来ないかどうか試していました。手伝ってくれた方々ありがとうございました。

限界サテライト側の機材不足で、音声がクリアに拾えないという問題があったため、結局配信は無しということになりました。悔しい・・・

昼飯を食ったあとは完全に体力の限界という感じでした。でも家に帰る手段も無いのでこのまま午後も見ることにしました。あとこれは秘密ですが、気づいたらメイド服を着ていました。

午後の部

とっても楽しい問題の始まりです。今回は時間内に解けた問題が全然ありませんでした。チクショー

因みに問題と解答はここです

問1

welcome.txtというファイルに仕込まれたバイナリを解析して、AAを見つける問題。いきなりヘビー過ぎて泣いた。とりあえずxxdしてみると不思議な模様があったので目を細めて見てみると0x00が紛れていたので、sedしてみました

するとめちゃめちゃなAAが出てきたので、適当にターミナルの横幅を動かしてみると70ぐらいだと解りました

cat welcome.txt | sed 's/\x00/@/g' | fold -70

因みに幅が70だったのは、toiletコマンドの出力の幅が70だったからだそうです。なるほどな〜〜〜〜

問2

フォーマットがめちゃくちゃなファイル名を揃える問題。こういうのはよくありそうだし、できると最高かもしれないですね

これはゴリゴリやればいいなとおもったので、ゴリゴリ。

ls -1|nkf -Z|sed 's/[0-9]/& /g;s/[aA-Z]/ & /g'|sed -r 's/^([0-9]).*([aA-Z])[^組]/\1年\U\2組/g'|sed 's/組組/組/g'|paste <(ls -1) - | xargs -n2 echo "mv" | bash

まずsedで年次と組を分離し、その後またsedしました。ちょっと冗長ですねこれ

因みに、ぼくは全角英数と半角英数が混ざっていると死にます。

問3

2018年の日付のうち2,3,5,7が4つ含まれる日付を列挙する問題。 例えば2018/07/23と言った感じ。
4つあるかどうかgreptrで削ったあとawklengthを見ればいいなと思っていたんですが、日付の列挙がうまく出来なかった・・・

時間内には解けなかったんですが、dateutils.dseqというコマンドがあるよということだったのでそれを使って解いてみました。

dateutils.dseq 2018-01-01 2018-12-31|sed -E 's/[^2357]//g'| paste - <(dateutils.dseq 2018-01-01 2018-12-31)|awk 'length($1)==4{print $2}'

pasteを使えるようになってから、よく使うようになりました。とっても便利ですよねこのコマンド

問4

tanzakuファイルをcatすると・・・

$ cat tanzaku
┏ ーー-┷-ーー┓
┃       ┃
┃       ┃
┃       ┃
┃       ┃
┃       ┃
┃       ┃
┃       ┃
┗ーーーーーー┛

このように表示されるのでこの中に俳句を入れる問題。ゴリゴリでいけそう

字余りするところは全角スペースで埋めてtetayoko。そのあとはsedの後方参照をつかってそれーという感じ。見た目ほど難しくなかった

問5

cowsayコマンドの出力を右向きにする。ただし文章はひっくり返しちゃダメ。
見た瞬間うっとなるのは響け!ユーフォニアム問題に似たものを感じる。

これは最初にrevしたあとsedで行を選択して末尾にスペースを埋め込んでいく戦法を考えました。でもあんまりよくないし何よりもめんどくさいので脳を休めてた。

問6

seq 20のうち素数である番号を○で囲む問題。

1
②
③
468
9
101214
15
161820

こういう感じですね。午前でやったことを活かして行こうと思い。まず②のxxdを見る。ASCIIコードを見つけて、それを基準に差分を足していけばいいのでは?と思ったのでゴリゴリしてみる

seq 20|factor|awk 'NF==2{print $2}'|xargs -I@ echo "echo \$((0xe291a1+@-2))"|bash|bc <(echo "obase=16") |tr '[A-F]' '[a-f]'|sed 's/$/0a/g'|xxd -p -r|paste <(seq 20|factor|awk 'NF==2{print $2}') -|awk '{print "s/^"$1"$/"$2"/g"}'|sed -f- <(seq 20)

前回のシェル芸勉強会で覚えた-f-も使えたので良かった。ちょっと冗長なので、他のシェル芸人さんみたいにスマートなやり方も鍛えていきたい

問7

textというファイルには見えない文字が含まれているらしい。どこにどんなのがあるか調査する問題。

調査するというのが難しかったので、とりあえずどんなのがありそうなのかbatで見る。すると・・・

丸見えになったのでコレで良いのではとなってしまった。この辺でもう脳が死んでたのでこんな解答しか出来なかった・・・

問8

最後はルビをふる問題。シェル芸人からの挑戦状を読んでいたので、sedで送り仮名を削りつつ、ルビのペアを作るのは出来てたけど上につける時のスペースの入れ方がわからなくてダメだった。

column -tでいいよということだったので覚えていきたい。

LTしたかったやつ

都合でいつものパワポテーマで作れなかったんですが。また難読化でLTする予定でした。今回は日夜手で難読化しているシェル芸人さんたちのために難読化コンバータを作りました。Go製です。ぜひ使ってみてください

因みにぼくは使ったことないです

まとめ

シェル芸勉強会はやはりサテライトでみんなで集まってやるのがたのしいですね。一人でサテライト開いても寂しいだけでした。問題が激しかったので寂しがっている暇はありませんでしたが。次回も参加したいなーとおもっています

今回もとても楽しかったです!ありがとうございました!!!