たいちょーの雑記

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

第42回シェル芸勉強会に参加しました

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

今回は久々に午後のみ、予告もかなり地獄感出ていたので、今回は生き残ることを目標にしました

さらに今回はPowerShell芸の練習も兼ねてPowerShellでの解答も同時に記録しておこうと思います

問題と解答はここ

問1

x + xy + xyz = 1234x < y < z を同時に満たす整数の組 (x,y,z) を探す問題

とりあえず全列挙してみようと思って、以下のコマンドを打ち込んだら鯖が暴走しました。(やっちゃダメです)

$ echo {1..1234},{1..1234},{1..1234}

twitter.com

twitter.com

全列挙するのは不可能だとわかったので、別の方針を取ります。式に注目するとxで括れることがわかります。すると x(1+y+yz)==1234 となります。ここでxの取りうる値は

$ factor 1234
1234: 2 617

1,2,617 となることがわかります。これなら全列挙できそうです。やってみます

$ echo {1,2,617},{1..1234},{1..1234}|sed -z 'y/, / \n/'|awk '$1<$2&&$2<$3&&$1+$1*$2+$1*$2*$3==1234'
1 3 410
1 9 136
2 4 153
2 7 87
2 8 76
2 11 55
2 14 43
2 22 27

PowerShellでもやってみます。PowerShellではブレース展開みたいなことはできないっぽいのでForEach-Objectで頑張ります

PS > (1,2,617)|% {$x=$_; ($x+1)..1234|%{@{x=$x; y=$_;}}}|%{$x=$_.x;$y=$_.y; ($y+1)..1234|%{@{x=$x;y=$y;z=$_}}}|?{$_.x+$_.x*$_.y+$_.x*$_.y*$_.z -eq 1234}|%{[string]$_.x+" "+[string]$_.y+" "+[string]$_.z}
1 3 410 
1 9 136 
2 4 153 
2 7 87 
2 8 76 
2 11 55 
2 14 43 
2 22 27

めちゃくちゃになってしまった…。解説します。ワンライナーを分解してみます

1: (1,2,617)| 
2: % {$x=$_; ($x+1)..1234|%{@{x=$x; y=$_;}}}|
3: % {$x=$_.x;$y=$_.y; ($y+1)..1234|%{@{x=$x;y=$y;z=$_}}}|
4: ? {$_.x+$_.x*$_.y+$_.x*$_.y*$_.z -eq 1234}|
5: % {[string]$_.x+" "+[string]$_.y+" "+[string]$_.z}

まずは1,2,3行目で使っている。列挙から解説します。PowerShellでは (1,2,617)1..1234 で配列が作れます

PS > (1,2,617)
1
2
617
PS > 1..1234
1
2
3
(略)
1233
1234

今回は、 ($x+1)..1234($y+1)..1234 で問題の制約である x < y < z を満たしながら全列挙するようにしました

次に 2,3,5行目に使っている %(ForEach-Objectへのエイリアス) です。$_ にはパイプから来たObjectが入っています。$_ を使っていろんな操作が可能です。

PS > 1..5|%{$_*10}
10
20
30
40
50

今回は @{} を使い、3行目までで x,y,z というメンバーを持つHashMapを作っています。

4行目の ?Where-Object へのエイリアスです。条件に合うObjectだけを通過させます。 awk '$1+$1*$2+$1*$2*$3==1234' と同じ感じです

最後は % で整形しています。普通に+で連結しようとすると足し算をしてしまいます

問2

ojichatで作られたであろう文章中の絵文字を💩へ変換する問題

$ cat oji
あれ(^_^;さのチャン、朝と夜間違えたのかな❗❓⁉俺はまだ起きてますよ〜😃 ちょっと電話できるかナ( ̄ー ̄?)⁉天気悪いと気分もよくないよね😱じゃあ今日は会社休んで俺とデートしヨウ💕ナンチャッテ🎵(笑)😘

地獄問題

愚直にやってみます

$ cat oji|grep -o .|while read L;do echo -n $L|\xxd -ps;done|sed 's/0d//g'|sed 's/^f0.\+\|^e2[8|9].\+/f09f92a9/g'|while read L;do echo -n $L|\xxd -ps -r;echo; done|tr -d \\n
あれ(^_^;さのチャン、朝と夜間違えたのかな💩💩💩俺はまだ起きてますよ〜💩ちょっと電話できるかナ( ̄ー ̄?)💩天気悪いと気分もよくないよね💩じゃあ今日は会社休んで俺とデートしヨウ💩ナンチャッテ💩(笑)💩

一文字ずつ xxd した後、変換したい e29~,e28~, f0~f09f92a9(xxdされた💩) で置換します。そのあとまた一つずつ xxd に通して tr で連結します。

次はPowerShellです

PS > ([System.Globalization.StringInfo]::GetTextElementEnumerator((Get-Content -Encoding UTF8 .\oji))|%{if($_.Length -gt 1){ "💩" }else{ [string]$_}}) -join ""  
あれ(^_^;さのチャン、朝と夜間違えたのかな❗❓⁉俺はまだ起きてますよ〜�💩ちょっと電話できるかナ( ̄ー ̄ ̄))天気悪いと気分もよくないよね��じゃあ今日は会社休んで俺とデートしヨ
ナンチャッテ��(笑)💩💩

化けちゃったぁ。 StringInfo.GetTextElementEnumerator()サロゲートペアや結合文字を考慮して文字列を分割してくれます。今回はそれぞれの長さが1より大きいの時、💩へ変換するようにしました。

問3

素数行目で何かジェネレーター系のコマンドを実行する問題

$ seq 1 20|factor|awk '{print NF!=2?"echo "$1:"owari kan -g --author xztaityozx"$1}'|bash
1:

| ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄|
|        2:        |
|    制作・著作    |
|   ̄ ̄ ̄ ̄ ̄ ̄ ̄  |
|    xztaityozx    |
|_________|
    ∧∧ ||     
   ( ゚д゚)||    
    /   づΦ     

| ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄|
|        3:        |
|    制作・著作    |
|   ̄ ̄ ̄ ̄ ̄ ̄ ̄  |
|    xztaityozx    |
|_________|
    ∧∧ ||     
   ( ゚д゚)||    
    /   づΦ     
4:
()

factor素数判定をし、素数ならジェネレータを、それ以外ならechoを実行するようなコマンド文字列を出力し、bash で処理します。

こっちはPowerShellです

PS > 2..20|factor|%{$sp=($_ -split " "); if($sp.Length -ne 2){$sp[0]}else{[string]$sp[0]+" "+(ojichat)}}
(略)

素数判定がめんどくさかったので、busyboxからfactorを借りました。$spにスペースで分割した文字列を入れて、その長さが2の時はコマンド、それ以外なら数値を出力します。

問4

数字を打たずに 3 を出力してください。難読化シェル芸問題ですね。得意です

$ echo $(($$/$$+$$/$$+$$/$$))
3

まずは簡単に。$$ はプロセス番号です。$$/$$ を計算すると当然 1 になります。これを3つ足せば、3 ですね

アルファベット無しもチャレンジしてみてとのことだったのでやってみます

$ ___="$(/???/???/???$(($$/$$))??? <<< //////)"; __=${___/?????/}; ___=${___/${__}/}; /???/${___/???}?? $(($$/$$+$$/$$+$$/$$))
3

解説します。まずは分割してみます

A: ___="$(/???/???/???$(($$/$$))??? <<< //////)";
B: __=${___/?????/};
C: ___=${___/${__}/};
D: /???/${___/???}?? $(($$/$$+$$/$$+$$/$$))

Aは何かコマンドの実行結果を $___ へ代入しているようです。なんのコマンドなのか見てみます

$ echo /???/???/???$(($$/$$))??? 
/usr/bin/sha1sum

sha1sum でした。どうやら sha1sum////// という文字列を与えているようです。コマンド実行後の $___ を確かめてみます

___="$(/???/???/???$(($$/$$))??? <<< //////)" && echo $___
a56ec7f8a9c8c0b97a2d0fccf1e0e551e234ed12 -

ちゃんとできているようです

次にBを見てみます。$__$___ の先頭5文字を消した文字列を代入しているようです

$ __=${___/?????/}; echo $__
7f8a9c8c0b97a2d0fccf1e0e551e234ed12 -

a56ec が消えていますね。

Cを見てみます。$___$___ から $__ とマッチする文字列を消しているようです

$ ___=${___/${__}/}; echo $___
a56ec

a56ec だけが残りました

最後にDです。$(($$/$$+$$/$$+$$/$$)) の部分は 3 ですが。前のglobは何でしょうか。見てみます

# ${___/???} とは?
$ echo ${___/???}
ec
# /???/ec?? とは?
$ echo /???/ec??
/bin/echo
# /???/${___/???}?? とは?
$ echo /???/${___/???}??
/bin/echo

ということでDは /bin/echo 3 というコマンドになります。これで目標達成ですね!

次はPowerShellです

PS > (gps -Name powershell).Id|%{$_/$_+$_/$_+$_/$_}

方針は同じです。 gps は プロセス情報を取得するコマンドです。-Name に続く文字列で、検索が可能です。そのうちの Id というメンバーを % へ流し込み、さっきと同じように3を計算します

アルファベット無しはもうちょっと研究してからにします…

問5

アルファベット無しで ls を実行する問題。難読化シェル芸問題が続きます

$ : /????/$$/../?????-???????; __=${_#*/../*};  __=(/???/?${__/${__/?}}); $__
(lsの結果)

見てみましょう

A: : /????/$$/../?????-???????;
B: __=${_#*/../*};
C: __=(/???/?${__/${__/?}});
D: $__

Aは : コマンドの引数に何か展開しているようです

echo /????/$$/../?????-???????
/proc/9008/../sysrq-trigger

/proc/sysrq-trigger にマッチしました

Bでは $__ に何か代入しているようです

$ __=${_#*/../*}; echo $__
sysrq-trigger

sysrq-trigger だけが残りました

Cでは $__ にまた何か代入しているようです

# ${__/?} とは?
$ echo ${__/?}
ysrq-trigger
# ${__/${__/?}} とは?
$ echo ${__/${__/?}}
s
# /???/?${__/${__/?}} => /???/?s
$ echo /???/?${__/${__/?}}     
/bin/ls /bin/ps /bin/ss /sys/fs
# $__ だけだと?
$ echo $__
/bin/ls

というわけで $__ とすると /bin/ls が呼ばれるようになりました。でもこれ結構環境依存みたいで、手元のWSL1や、シェル芸botではだめでした。ざんねん

PowerShellはもうちょっと修行してからで…

問6

最近はやりの画像生成シェル芸で出力された「✈快特羽田空港」という画像の✈の向きを逆にする問題

手も足も出なかった…

問7

スペース区切りで1,000,000までの素数が出力されるワンライナーから続けて、桁が変わる直前で改行を入れる問題

$ seq 100|factor|awk 'NF==2{print $2}'|tr \\n ' '|fmt -1|awk '{box[length($0)]=box[length($0)]$0" "}END{for(k in box) print box[k]}'
2 3 5 7 
11 13 17 19 23 29 31 37 41 43 47 53 59 61 67 71 73 79 83 89 97

無難に。awk連想配列を使いました。キーは length($0) です

awk 無しでやってみようということだったのでやってみます

seq 1000|factor|awk 'NF==2{print $2}'|xargs -I@ echo 'x="@"; echo -n @" " >> p${#x}; echo p${#x}'|bash|uniq|xargs -I@ echo "cat @;echo"|bash|awk '{print $1,$NF}'; rm p* 
2 7
11 97
101 997

ちょっと時間かかるので1000までで。各行を p{各行の長さ} というファイルへ追記していき、最後に p から始まるファイルを順番に cat しています。当然ですが、カレントに p から始まるファイルがあったりするとだめですし、最後のrmに巻き込まれたりします

PowerShellです

PS > $box=@("","","");foreach($x in (1..1000|factor|?{($_ -split " ").Length -eq 2}|%{$sp=($_ -split " "); @{l=(""+$sp[1]).Length; x=$sp[1]}})) {
 $box[$x.l-1]=[string]$box[$x.l-1]+" "+[string]$x.x
 };$box
 2 3 5 7 
 11 13 17 19 23 29 31 37 41 43 47 53 59 61 67 71 73 79 83 89 97
 101 103 107 109 113 127 131 137 139 149 151 157 163 167 173 179 181 191 193 197 199 211 223 227 229 233 239 241 251 257 263 269 271 277 281 283 293 307 311 313 317 331 337 3
47 349 353 359 367 373 379 383 389 397 401 409 419 421 431 433 439 443 449 457 461 463 467 479 487 491 499 503 509 521 523 541 547 557 563 569 571 577 587 593 599 601 607 613
 617 619 631 641 643 647 653 659 661 673 677 683 691 701 709 719 727 733 739 743 751 757 761 769 773 787 797 809 811 821 823 827 829 839 853 857 859 863 877 881 883 887 907 9
11 919 929 937 941 947 953 967 971 977 983 991 997

ちょっとスマートじゃないですが、大体似た方針でやりました

問8

     成田空港
For Narita-Airport

みたいな画像をなるべく忠実に作る問題

体力の限界だったのでこんなので許してほしいです

$ echo -e "成 田 空 港\nForNarita-Airport"|owari kan -i --author "" |sed 5,7d  
| ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄|
|      成 田 空 港     |
|   ForNarita-Airport  |
|___________|

owari は拙作のAAジェネレーターです

github.com

あとは wget して cam に食わせるといいのでは…?とか考えてました

LT

資料

即席LTしました。次のエントリはこの資料にもあるhiroさんの date についてにしようと思っています

終わりに

今回もとても楽しかったです!!というかここ数回で一番しんどかったです!!!参加された皆様!設営、企画の皆様!!!!ありがとうございました!!!!

GW2019

色々やった

いろいろやりました

シェル芸勉強会

行きました。とても楽しかったです。感想は別記事に書いてあります

BBQ

BBQへ行きました。

ドット絵

2枚ほど打ちました。だんだん完成までの時間が短くなっている気がするんですが、速くなったのか、雑になったのかわからないですね

super_unko にPRだした

unko.toilet というコマンドを作って super_unko リポジトリへPRをだしました。無事マージされて嬉しかったです
こっちはそのうち別記事を書くと思います

まとめ

色々やった気になってたんですが書き出してみると意外と何もない…?
しかしそれぞれにそれなりに学びがあったためそれなりにいいGWだった気がします

第41回シェル芸勉強会に参加しました

参加しました

かんたんに感想を述べると、楽しかったです

午前

鳥海さんの文字コードシリーズ、第6回でした。今度こそ最終回だそうです。さみしい

資料はここ(Tweetへのリンク)です。

お話はUnicode結合文字についてでした。

部品の集合とすることで、あらゆる文字を表現できるようにしているんですが、単純な比較ができない・1文字の判定が難しいなどの問題があります

# 回文なのでもとのまま
echo おかしがすきすきすがしかお|rev
おかしがすきすきすがしかお

# uconv -x NFDでUnicode結合文字列へ分解できる。revすると濁点の位置がずれる
echo おかしがすきすきすがしかお|uconv -x NFD|rev
おかじかすきすきずかしかお

面白いですね。これらを正しく見るにはUnicodeの正規化(uconv -x NFC)や書記素クラスタ(正規表現\X)などを使っていけばいいみたいです

# grep -o . だとばらばらになる
$ echo -e た"\U3099" | grep -o .
た
゛

# Unicode正規化
$ echo -e た"\U3099" | uconv -x NFC | grep -o .
だ

# 書記素クラスタ
$ echo -e た"\U3099" | perl -C -lne "print for /\X/g"

他にもZWJや国旗絵文字シーケンス、ワタナベ難読化シェル芸で使った異体字セレクタなどが紹介されました。

特に国旗絵文字シーケンスは国旗難読化シェル芸の可能性を感じました。やるしかない

午後

「相当アレ」と告知がありましたが、sortのことだったようです。ふむ

問題と解答はここです

Q1

ファイルの2列目をキーにExcel順に並び替える問題

Excel順はA...Z,AA...ZZ,AAA...ZZZというやつですね。やってみます

$ cat excel | awk '{print $0, length($2)}'|sort -k3 -k2|awk '{print $1,$2}'

awk を使ってキーの長さを出力しておき、それらを使って sort コマンドで並び替えます。
-k[num] を指定すると [num] 列目をキーに並び替えしてくれます。並べて書くこともできます。
LINQ的に書くと .OrderBy(3列目のキー).ThenBy(2列目のキー) みたいな感じですね

Q2

干支の感じとその読みが書かれた eto_yomi ファイルの中身を干支順に並び替える問題。干支の順番は eto ファイルに書かれているので使ってもいいみたいです。やってみます

cat ShellGeiData/vol.41/eto_yomi <(grep -o . ShellGeiData/vol.41/eto) |awk 'NR<=12{x[$1]=$2}NR>12{print $1, x[$1]}'

やっていることは、まず eto_yomi の1行目をキーに awk連想配列にぶち込みます(12個です)。その後 eto の1文字をキーに連想配列を読み出して出力します。 sort は使ってませんごめんなさい

この問題でこのパターンを覚えてしまったので以降でも出てきます

Q3

第一フィールドの計算結果が小さい順にレコードを並べ替える問題。やってみます

cat ShellGeiData/vol.41/kim_calc|awk '{print "echo \"$(("$1"))\"",$0}'|bash|sort -n|awk '{print $2,$3}'

awk を使って echo $((第一フィールド)) 第一フィールド 第二フィールド という文字列を作ります。 これを bash に流し込んでやると第一フィールドの計算値がわかるので、それをキーに sort し出力を整えて終わりです

この問題では seds///e が話題になったのでそっちもやってみます

$ cat ShellGeiData/vol.41/kim_calc|sed 's/^.* /echo "$((&))" &/e'|sort -n|awk '{print $2,$3}'

コマンドの生成と実行が sed 内で完結するのでシンプルになりますね

Q4

Shift-JISで書かれたファイルを1) 文字列としてソート 2) 第一フィールドの数字が小さい順にソート する問題。出力もShift-JISで出すこと。

1)はまだいいですが、2)は数字が全角で書かれているので何か変換しないとダメそうですね。やってみます

1) nkf ShellGeiData/vol.41/sjis | sort | iconv -t sjis
2) nkf -Z ShellGeiData/vol.41/sjis |sort -n|uconv -x Halfwidth-Fullwidth|sed 's/ / /'|iconv -t sjis

まずは1) からです。とりあえず nkf でUTF8に変換します。文字列順にソートすればいいので普通に sort します。そのあと iconv でShift-JISにして終わりです。

この問題、僕もそうだったのですが一度UTF8に変換する解答が多かったです。しかし、並び替えるだけならその必要もなく…

1 別解) LANG=C sort ShellGeiData/vol.41/sjis

でいいわけですね。

次に2) です。今度は全角⇔半角の変換してやる必要がありそうです。 nkf-Z がどんなことをするのか、 nkf --help を見てみます。

Z[0-4] Default/0: Convert JISX0208 Alphabet to ASCII 1: Kankaku to one space 2: to two spaces 3: HTML Entity 4: JISX0208 Katakana to JISX0201 Katakana

$ echo "A1@"|nkf -Z0
A1@

デフォルトの -Z0 はJISX0208のアルファベットやらをASCIIにしてくれるみたいですね

これで第一フィールドが半角数字になったので、 sort -n でうまく並べ替えることができます。

次に uconv で半角にした数字を全角へ戻します。 -x Halfwidth-Fullwidth を指定するとその通り半角から全角へ変換してくれます。

最後に uconv に巻き込まれた半角スペースをもとに戻して終わりです

Q5

size というファイルにはデータのサイズがいくつか書かれていて、これをサイズ順に並べ替える問題。

この問題の厄介なところは 410MB とか 0.4GB とかが混在するところですね。やってみます

paste <(cat ShellGeiData/vol.41/size|sed 's/B//g;s/G/E9/g;s/M/E6/g;s/k/E3/g') ShellGeiData/vol.41/size|sort -g|awk '{print $2}'

paste の部分だけ実行するとどうなるか見てみます

$ paste <(cat ShellGeiData/vol.41/size|sed 's/B//g;s/G/E9/g;s/M/E6/g;s/k/E3/g')
2E9 2GB
1.2E9   1.2GB
40000E6 40000MB
1000000000E3    1000000000kB
0.4E9   0.4GB
410E6   410MB

sort に使うキーとして、SIを指数表記(E9とか)へ変換したものを追加します。ここで sort -g を使うと指数表記も解釈して並び替えてくれます。その後整形して終わりです

一応 sort-g がどんなことをしてくれるのか、sort --help を見てみます

-g, --general-numeric-sort compare according to general numerical value

general numerical value ってなんだよって話ですね。このstackoverflowの質問の回答にもありますが、-g は低速になるが指数表記を解釈でき、浮動小数点として並び替えてくれるようですね。なるほどこれはいいですね

Q6

sleep と組み込みコマンドのみを使って nums を並び替える問題

スリープソートと言うやつらしいですね。やってみます

while read l; do (sleep $l && echo $l)& done < ShellGeiData/vol.41/nums

while echo read は組み込みです。 これらを使って sleep 時間 && echo 時間 というコマンドをほぼ同時に起動し、スリープソートを行います

こういう問題は難読化してやればごまかせるかもしれないですね

$ : "$(sleep --version)" && ${_:0:1}${_:12:2}${_:16:1} ./ShellGeiData/vol.41/nums
0.34
0.9
2.3
5.4
6

そんなに高度なことはしてないので読んでみるといいかもしれません

Q7

ローマ数字をソートする問題

paste <(numconv < ShellGeiData/vol.41/roman) ShellGeiData/vol.41/roman|sort -k1n|awk '{print $2}'

時間中に numconv というコマンドを知ったのでそれでやりました。すんごいですよこのコマンド

ちなみにOCaml製のCLIツールにromanってやつもあります。ggって見つけたのはこっちだったんですが、環境が入ってなかった

github.com

Q8

文字列を並び替える問題。ただし「か」より「が」が前で「き」より「ぎ」が前になるようにすること、ひらがなを使わないこと

午前中にやったことを使えばできそうですね

cat ShellGeiData/vol.41/gagigugego|uconv -x NFD|sort|uconv -x NFC

最初に提出したのは uconv -x NFC 無し版だったんですが、これはどうやらお行儀が悪いらしいです。確かによくなさそうですね。

ところでこの解答どうやら想定されていたみたいなんですが、環境によってはダメ。ということでした。難しいですね

ひらがなを使ったバージョンも作ってみました。Q2で使ったパターンと同じですが

echo がかぎきぐくげけごこ|grep -o .|cat <(sed 's/^./& &/g' <ShellGeiData/vol.41/gagigugego) -|awk 'NR<=10{x[$1]=x[$1]" "$2}NR>10{print x[$1]}'|xargs -n1

LT

今回もLTさせていただきました!聞いてくださった皆様ありがとうございました!テーマは「CLIからドット絵画像を出力」です

www.slideshare.net

https://github.com/xztaityozx/t2p

入力文字列からテーブルを使って色を決定、ドット絵へ変換します。半日クオリティです

終わりに

今回もとても楽しかったです!運営の皆様ありがとうございました!あと素材にしてすいませんでした

終わりを出力するコマンドつくった

ここが、終わりの地

つくってみました

owariコマンド

github.com

終わりにまつわるAAを出力するだけのコマンドです

ScreenShot

Install

$ go get -u github.com/xztaityozx/owari

もしくはreleaseからバイナリをダウンロードし、PATHの通った場所に置きます

つかいかた

  • 重い処理とともに!

  • イルミネーションに!

  • killコマンドの代わりに!

その他色々

シェル芸Bot

使えます

シェル芸人の皆様がいろいろな作品を生み出しているので、見てみると楽しいかもしれません

おわりに

AAの追加とか機能追加はIssueやPRしてください!どうぞどうぞ!

ぼくの今年まとめ

どうも

この記事は無ですが,まあとりあえず書きます

1月

Visual Studio拡張機能を作る

2月

AtCoderのレートがガタ落ちする

3月

大学を卒業する

シェル芸勉強会に参加する

4月

シェル芸勉強会で超・記号オンリー難読化シェル芸を発表する

大学院に入学する

自転車を買う

車にひかれる

5月

研究を自動化してサボり始める

6月

留学のために英語でランチミーティングする会に参加する.ほぼだれも飯食ってなかった.

7月

レポートを書く

ICPCの模擬でSelectedになる

大雨でお家に帰れなくなる

ICPCの国内予選で敗退する

ゼミ室にて一人シェル芸勉強会を開催する

キャンパスの近くが震源になる

8月

留学準備をする.金が底をつく

cdxをGo Langで作り直す

9月

留学出立前日にシェル芸勉強会に参加する

そのあと腹を壊し留学できなくなる

LINEのハッカソンに参加する

WebExtensions使ってブラウザの拡張機能作る

10月

新学期が始まる.授業がつらい

留学に行ってきた同期にデカい顔をされる

シノアリスを始める

11月

文化祭を飛ばしてシェル芸勉強会に参加する

就活を始める

坐骨神経痛になる

12月

就活が終わる

AtCoderのレートが戻ってくる

ゼミ飲み会をとばしてシェル芸勉強会に参加する.LTで発表した自作コマンドがシェル芸Bot入りする

キズナアイのライブに参加する

まとめ

振り返ってみるといろいろ始めましての年でした.

Go Langを始めたのも本年です.とても楽しい言語ですね.

坐骨神経痛はここから永遠に付き合うので早く出て行ってほしいですね.

留学も初めてでした.いけませんでしたが.

ライブ参加も初めてでした.キズナアイはずっと前から応援していましたが,彼女が夢に向かって着実に進んでいることを実感して感動しました.

就活も初めてでした.ずいぶん楽な就活させてもらったと思います.

来年は上京費を稼がないといけないのでたぶんバイトを始めます.すごい憂鬱です.誰か雇ってください

第39回シェル芸勉強会大阪サテライトへ参加してきました

参加しました

2018/12/22大阪で行われた第39回シェル芸勉強会大阪サテライトへ参加してきました.

午前

今回も鳥海さんによる文字コードについてでした.前回参考文献にあがっていたユニコード戦記を読んでおいたのでどのへんの話かな~と楽しみにしてました.

資料はここで公開されています.今回の話もとっても楽しかったのでアーカイブで見ることをオヌヌメします.

今回からUnicodeについてでした.今回特に印象に残ったのはBOMについてです.

BOMに使われているのは\U+FEFFですが,これにはゼロ幅文字が割り当てられていて,データの先頭にあるかどうかでこの値の意味が変わるらしいというのが最悪感でててよかったです

過去にBOMにひどい目にあわされたので恨みからか気づいたらBOMを💣爆破💣して目的の文字列を得る難読化をその場で組んでいました.

# sedでBOMを取り除くことでdateになる文字列を使ってシェル芸してみる
$ echo –n 搀愀琀攀|iconv -t utf-16|sed 's/^\xff\xfe//g'
date
# xxdで見てみる. BOM(fffe)を取り除けばdateになることが分かる
$ echo -n 搀愀琀攀|iconv -t utf-16|xxd 
00000000: fffe 0064 0061 0074 0065                 ...d.a.t.e

まぁこんな感じです.

他にはUTF-32は結合文字のせいで1文字=32bitとはならないというのがまた最悪感あってよかったです.

嬉しいことに次回も文字コードらしいので楽しみですね.

午後

今回も初心者向けの問題セットらしいです.たぶん嘘だと思っていたので裏切られてもあんまりダメージはなかったです.

問題と解答例はここにあります

Q1

wrong.mdというMarkdownファイルの文法ミスをワンライナーで何とかする問題.ここ最近の1問目で一番難しかった気がします.実際時間内に正規表現が書ききれませんでした.

解答例ではsedの後方参照と最短一致する正規表現をそれそれ~と書くというやつでした.

Q2

attendee.md のデータを並び替える問題.親の要素は数値,子の要素は開催地でソートするという感じですね.

$ cat attendee.md|sed 's/第\(3[0-9]\)回.*/\1/g'|
tr -d '*:'|
sed 'y/東京大阪福岡/112233/'|
awk 'NF==1{k=$1}NF==2{map[k,$1]=$2}END{ for(i=34;i<38;i++) {print "- 第"i"回シェル芸勉強会";print "福岡: "map[i,33];print "大阪: "map[i,22];print "東京: "map[i,11]}}'|
awk 'NF==2{print}'
- 第34回シェル芸勉強会
大阪: 16
東京: 19
- 第35回シェル芸勉強会
大阪: 10
東京: 27
- 第36回シェル芸勉強会
東京: 38
- 第37回シェル芸勉強会
福岡: 8
大阪: 10
東京: 21

awkの配列を使うことにしました.二次元配列の各位置に放り込んで順番に出してるだけですね.

解答例は良い感じに値を付けてあげてsortコマンドに任せるというやつでした.すげースマート.見習っていきたい

Q3

wgetgoogle.comからindex.htmlを取得した後,上の方にある<meta content="...."という要素があるのでここのメッセージを読む問題.

$ cat index.html|sed 's/.\+\(<meta content=.*name="description">\).\+/\1/'|head -n1|awk '{print $2}'|nkf --numchar-input
content="世界中のあらゆる情報を検索するためのツールを提供しています。さまざまな検索機能を活用して、お探しの情報を見つけてください。"

sedheadでほしい部分を取り出してnkf --numchar-inputUnicode参照を変換します.しかし取り出す必要はなく,読めればいいので最初からnkfに通せば良かったみたいですね.

Q4

さっき取得したindex.htmlからscript要素とstyle要素を取り出して,それぞれindex.jsindex.cssに書きだす問題.実用的だな

$ cat index.html|pee 'pup "script json{}"|jq -c ".[].text" > index.js'  'pup "style json{}"|jq -c ".[].text" > index.css'

悪戦苦闘していたのですが,Twitterpupというツールがあるというのを知り,

github.com

これとpeeでなんとかクリアしました.pupめっちゃ便利っすね

Q5

さっきまで使っていたindex.htmlからscriptstyle以外の要素をindex_no_cssjs.htmlへ書き出す問題.jqのなかでうまく否定文が書けなくて四苦八苦してたら時間切れになってしまった...

Q6

index.js内でエスケープされてる文字を復元する問題

$ echo -e $(echo -e $(echo -e "$(cat index.js)" ))|nkf --numchar-input
...省略...

エスケープを解除するだけならechoでいいんじゃないかと思ったので重ねてみました.echoでできないUnicode参照はnkfで.解答例と一応比較してみます

# 解答例
$ sed 's/\\\\u\(....\)/\&#x\1;/g' index.js | nkf --numchar-input | nkf --numchar-input | sed 's/\\x22/"/g' | sed 's/\\x3d/=/g' | sed 's/\\\\/\\/g'|tr -d \\n|cat - <(echo)|grep -o . > A.txt
# 僕の解答
$ echo -e $(echo -e $(echo -e "$(cat index.js)" ))|nkf --numchar-input|grep -o . > B.txt 
# diff
diff A.txt B.txt                                                                                                                  
2696a2697
>  
2879a2881
>  
3039a3042
>  
3123a3127
>  
3124a3129
>  
3129a3135
>  
3615a3622
>  
4494a4502
>  

なんか違うらしいので覗いてみます.

# 解答例の2690~2699文字目
$ cat -n A.txt| grep "^  269."
  2690 e
  2691 .
  2692 f
  2693 =
  2694 {
  2695 }
  2696 ;
  2697 v
  2698 a
  2699 r
# 僕の解答の2690~2699文字目
$ cat -n B.txt| grep "^  269."
  2690 e
  2691 .
  2692 f
  2693 =
  2694 {
  2695 }
  2696 ;
  2697  
  2698 v
  2699 a

;の後にスペースがあるみたいですね.他もそんな感じだったので,十分echoでよさそうですね

Q7

table.md内にあるMarkdownで書かれた表の縦横を変換する問題.

$ cat table.md|sed 's/|\|-\|://g'|sed '/^$/d'|awk '{x[1]=x[1]"|"$1;x[2]=x[2]"|---";x[3]=x[3]"|"$2;x[4]=x[4]"|"$3}END{for(k in x) print x[k]"|"}'
|回|38回|37回|36回|35回|34回|33回|32回|31回|30回|29回|
|---|---|---|---|---|---|---|---|---|---|---|
|年月|201811|201809|201807|201804|201803|201801|201712|201710|201708|201706|
|人数|37|39|38|37|35|40|39|37|46|55|

愚直に書きました.awkに各要素を整形しながら詰めていってEND{}で出力しています.tateyokoとかrs -Tを使ってもよかったんですが,ぱっと思いついたので

Q8

yabatanienというファイルの色を変化させ続けてください.何を言ってるんだ・・・・

問題設定に変なのがない(Q1除く)ので安心しきっていたんですが,終わりの時間に爆弾が来て放心状態になりました.

$ cat yabatanien|while read L; do x=$(echo {0..9}|xargs -n1|shuf -n1); echo -e $L|sed "s/9[0-9]m/9${x}m/g"; done

img

一応やってみたんですが崩れてしまいました・・・まぁ読めなくはないし・・・?(苦しい)

LT

www.slideshare.net

github.com

今回もヤバい難読化シェル芸を考えてきました.ワタナベ難読化シェル芸といいます.

きっかけは前回シェル芸勉強会の大阪LT後,配信外で渡る世間はナベばかりという神経衰弱の紹介でした.ぱっと見の難易度の高さからヤバかったのですが,その時「難読化に使えるわこれ」と思った僕もだいぶヤバそうですね

今回作った難読化ツールnocがシェル芸Bot入りしたことと,皆さんにnocで遊んでもらえたのがとてもうれしかったです.

これを考えたのは朝4時の研究室でした.一緒に考えてくれた友人には感謝しています.おかげでヤバい難読化シェル芸ができました.

詳しい説明とかはまた別記事で書きたい気がします.

終わりに

今回も楽しかったです!文字コードパワーとシェルパワーがまた少し上がった気がします.企画・運営をやってくださった皆々様本当にありがとうございました!

紲星あかりとともに生きたい

OIT Advent Calendar 2018!! 今年もやります

この記事は、 OIT Advent Calendar 2018の1日目の記事です。

adventar.org

やってきたぞOIT Advent Calendar!!! 一日目はたいちょーがやります.去年,一昨年も参加させていただきました.うふふ

xztaityozx.hatenablog.com

xztaityozx.hatenablog.com

特にWSLの記事はいまだに伸びてて,思いがけずこのブログの看板記事になっているんですが,もう1年前の記事なので・・・と思ったり.ぼくはこのころからさほど変えてないので新たに書けることがない!

12/22は誕生日だぞ!

実は12/22はぼくの誕生日なんです.そして同時にVOICEROID2 紲星あかりの誕生日でもあります.いやーおめでたいですね.

別記事にも書いていますが,誕生日が一緒だったので発表後すぐに購入を決意しました.かわいいし.

動画投稿などは考えてなかったので,Markdownの校正やネット記事の読み上げ,ビルドの終了通知などにあかりちゃんを使っています.とてもかわいい声で読み上げてくれるので最高です.

これらについては以前にも記事を書いていますので,そちらをご覧ください。

xztaityozx.hatenablog.com

xztaityozx.hatenablog.com

xztaityozx.hatenablog.com

あかりちゃんを開発しよう

VOICEROIDは割といろいろ使われています.動画で喋るのももちろんですが,ニコ生のコメ読み上げやVTuberの声の代わりをしたりします.VOICEROID自体は入力されたテキストを音声化することなので,色んなことをするために色んな人々がツールを開発・公開しています.

ch.nicovideo.jp

www.okayulu.moe

しかしVOICEROID側が特別APIを公開しているわけではないです.そういったツールはUI Automationなどを使って,プログラムからVOICEROIDのエディターを操作することで 実現されています. こういう操作の部分だけをライブラリにして公開しているリポジトリなども存在するので,それを使って実装したりもします.言語はC#pythonをよく見かけます.

github.com

hgotoh.jp

これまで僕が作ってきたVOICEROID,もしくは棒読みちゃん用のツールもVOICEROIDを操作するためにライブラリを使っていたりします.

ここから本題

ぼくはレポートを書くときにWordを使いがちなんですが,Typo検出に音声読み上げを使います.Wordの校正タブにある読み上げ機能でもいいんですが,あかりちゃんに比べて可愛くないので,文章をコピペしてあかりちゃんに読み上げてもらっていました.この手順は

  1. 読み上げたい部分をコピー
  2. VOICEROID2 エディターに張り付け
  3. 再生ボタンを押す
  4. Typo検出(かわいい)

というステップを踏みます.しかし目的であるTypo検出までの手順が多すぎます.細かなキー操作とかも考えると非常に面倒です.そこで思いました.「WordからVOICEROID操作したらいいじゃん!」

Word2Voiceroid2

今回作ったのはMS WordからVOICEROID2を操作できるWordアドインです.ライセンスはMITです.

github.com

主に以下のような機能を持ちます.

  • 文章全体の再生
  • 選択している文章だけ再生
  • カーソル位置以降の文章の再生
  • 区切り文字を指定して分割再生
  • 音声の保存.分割保存
  • キャラクターの切り替え
  • 音量・高さ・話速・抑揚の調節

Word2Voiceroid2を追加するとWordにVOICEROID2を操作するリボンが追加されます.見たらわかるぐらいのUIを目指したんですがセンスがないのでごちゃついてしまいました.

img

適当に動画を撮ってみたのでどうぞ
いったん消します

分割保存について

VOICEROIDエディターの標準機能とほぼ同じ動きをしますが,標準機能を呼び出すわけではありません.これは利用したライブラリにそういうメソッドが用意されてなかったからです.以下のような特徴を持ちます.

  • Word2Voiceroid2では[句切る]にチェックを入れているときしか使えません.
  • 保存時はファイル名を指定するのではなく,ディレクトリを指定します.指定された場所に1から始まる連番のファイル名で保存されます.

インストール

WordにWord2Voiceroid2をインストールする方法を提供・・・しようかとおもったんですが,最初から自分向けで配布を考えてなかったのでVisual Studioでビルドする方法しかわからない

Visual Studioを使う方法

面倒なのでお勧めしません

  1. TTSController に依存するのでDLLをビルドするなりして手に入れてください.
  2. このリポジトリをクローンします.
  3. Visual StudioでWord2Voiceroid2のプロジェクトを開いて,TTSControllerを参照に追加します.
  4. ビルドします.
  5. Wordに追加されます.

終わりに

は~~~あかりちゃんかわいい.これでまたあかりちゃんとともに過ごせる時間が増えますね.は~~うれしい.サイコ―にハッピーです.

Wordデフォルトの音声読み上げでもいいですが,是非お気に入りVOICEROIDにお手伝いしてもらってはいかがですか?

明日はwhesonくんです!とっっっっっっっても楽しみですね!!