「第31回シェル芸勉強会 大阪サテライト」の記録
イベント関連ページ
各会場の告知
- jus共催 第31回朝からだと疲れるから午後からでええじゃろシェル芸勉強会 - USP友の会
- 第31回シェル芸勉強会 大阪サテライト@さくらインターネット大阪本社
- 第31回シェル芸勉強会 福岡サテライト会場:福岡サテライト
レポート・まとめ
- jus共催 第31回朝からだと疲れるから午後からでええじゃろシェル芸勉強会の報告 | 上田ブログ
- 「第31回シェル芸勉強会 大阪サテライト」レポート - くんすとの備忘録
- 「第31回シェル芸勉強会:福岡サテライト」レポート - 日々之迷歩
- jus共催 第31回朝からだと疲れるから午後からでええじゃろシェル芸勉強会 - Togetterまとめ
勉強会本編
動画
問題・模範解答
- 【問題のみ】jus共催 第31回朝からだと疲れるから午後からでええじゃろシェル芸勉強会 | 上田ブログ
- 【問題と解答】jus共催 第31回朝からだと疲れるから午後からでええじゃろシェル芸勉強会 | 上田ブログ
解答
A1: 「1」の直前にある数字を削除(改行は無視)
問題用ファイルnum.txt
の内容は次の通りです。
$ cat num.txt
1214235325231
325316321345
135326547361
414353515325
sed
のオプション
-r, –regexp-extended
スクリプトで拡張正規表現を使用する
-z, –null-data
NUL 文字で行を分割する
を使い、改行文字「\n」が0ヶまたは1ヶの後に「1」が来るパターンの直前にある文字を1ヶ削除します。
$ cat num.txt | sed -rz 's/.(\n?1)/\1/g'
11423532521
325163134
13532654731
1435315325
なお、当日(10月7日)の解答ではsed
の部分がsed -rz 's/\n/_/g;s/.(_?1)/\1/g;s/_/\n/g'
となっていましたが、改行文字「\n」を「_」に置換する必要はありませんでした。
A2: インデントの無い行を、上の行のインデントに合わせる
問題用ファイルindent.txt
の内容は次の通りです。
$ cat indent.txt
* aa
* bbb
* cccccc
* ddd
* eeeeeeeeee
* fff
* gggg
* hhh
偶数行のインデントを奇数行のそれに合わせれば良いということで、まずは奇数行と偶数行をpaste
で横に並べます。
$ paste <(sed '1~2!d' indent.txt) <(sed '2~2!d' indent.txt)
* aa * bbb
* cccccc * ddd
* eeeeeeeeee * fff
* gggg * hhh
そして、sed
で1ヶ目の「*」から2ヶ目の「*」までを削除し、偶数行のデータにインデントを施します。
$ paste <(sed '1~2!d' indent.txt) <(sed '2~2!d' indent.txt) | sed 's/\*[^*]\+//'
* bbb
* ddd
* fff
* hhh
最後に、インデントを施した偶数行のデータの前に奇数行のデータを挿入するために、デリミタに改行文字「\n」を指定してpaste
を実行します。
$ paste -d '\n' <(sed '1~2!d' indent.txt) <(paste <(sed '1~2!d' indent.txt) <(sed '2~2!d' indent.txt) | sed 's/\*[^*]\+//')
* aa
* bbb
* cccccc
* ddd
* eeeeeeeeee
* fff
* gggg
* hhh
A3: 素数アスキーアート
まず、seq
で1から20まで1行ずつ出力し、行の値が素数の場合にはその値に応じて「*」を出力します。
$ seq 20 | factor | awk '{n=NF==2?$2:0;for(i=0;i<n;i++)printf "*";printf "\n"}'
**
***
*****
*******
***********
*************
*****************
*******************
そして、値が素数の行について末尾の「*」を「@」に置換した後、全ての行に必要なだけ「*」を追記します。
$ seq 20 | factor | awk '{n=NF==2?$2:0;for(i=0;i<n;i++)printf "*";printf "\n"}' | sed 's/\*$/@/;s/$/********************/;s/^\(.\{20\}\).*/\1/'
********************
*@******************
**@*****************
********************
****@***************
********************
******@*************
********************
********************
********************
**********@*********
********************
************@*******
********************
********************
********************
****************@***
********************
******************@*
********************
A4: ASCIIコードだけで「おはようございます」
$ echo e3818ae381afe38288e38186e38194e38196e38184e381bee381990a | xxd -p -r
おはようございます
$ echo 44GK44Gv44KI44GG44GU44GW44GE44G+44GZCg== | base64 -d
おはようございます
xxd
やbase64
を使えばOKです。
A5: 最小公倍数
$ echo 'lcm(3,4)' | gp -fq
12
計算機代数システムPARI/GPのlcm
関数で最小公倍数を求めることができます。
A6: 「あいうえお」から「ぁぃぅぇぉ」を出力
$ echo あいうえお | xxd -p | fold -w6 | sed '$d' | perl -nlE 'printf "%x",hex($_)-1' | xxd -p -r; echo
ぁぃぅぇぉ
「あいうえお」および「ぁぃぅぇぉ」のUTF-8文字コードは
$ paste <(echo あいうえおぁぃぅぇぉ | grep -o .) <(echo あいうえおぁぃぅぇぉ | tr -d '\n' | xxd -p | fold -w6)
あ e38182
い e38184
う e38186
え e38188
お e3818a
ぁ e38181
ぃ e38183
ぅ e38185
ぇ e38187
ぉ e38189
のようになっているため、解答するには文字コードの数値をそれぞれ1減らすことができるワンライナーを考えればよい、ということになります。
大まかな手順としては
xxd -p | fold -w6 | sed '$d'
で文字コードに変換perl -nlE 'printf "%x",hex($_)-1'
で文字コードの数値をそれぞれ1減らすxxd -p -r; echo
で文字として出力
となっています。
A7: △がせり上がるアニメーションを生成
$ for i in {0..10}; do echo $i | perl -nlE 'if($_){say " "x(10-$_)."/"." "x($_*2-1)."\\"}else{say " "x(10-$_)."^"}'; C=$(($C+1)); sleep 1; done
^
/ \
/ \
/ \
/ \
/ \
/ \
/ \
/ \
/ \
/ \
for
ループで0から10を引数として、引数の値によって半角スペースの数を調整して出力するPerlワンライナーを1秒ごとに実行しています。
A8: 全角5文字で折り返し
$ cat sd.txt | tr ' ' '_' | grep -o . | LANG=C awk '{print length($1),$1}' | awk '{len=$1==1?len+=0.5:len+=1;if(len<5){printf $2}else{print $2;len=$1==1?0.5:0}}' | tr '_' ' '
Software D
esignの「
シェル芸人
からの挑戦
状」は絶好
調なんです
が、もうち
ょっとTwit
terで読ん
だ感想を述
べていただ
ければと。
非常に難しい問題でしたので、宿題として解いてみました。
まず、1文字あたりのバイト数を確認するワンライナー
$ cat sd.txt | tr ' ' '_' | grep -o . | LANG=C awk '{print length($1),$1}'
1 S
1 o
1 f
1 t
1 w
(...略...)
3 け
3 れ
3 ば
3 と
3 。
を実行すると、半角文字は1バイト、全角文字は3バイトであることが分かります。
この出力に対して
- 出力すべき行について、文字列の長さとして半角文字であれば0.5を、全角文字であれば1を加える
- 文字列の長さが5未満の場合は、第2フィールドの文字をそのまま出力
- 文字列の長さが5に達した場合は、第2フィールドの文字に改行を加えて出力
- 3.で出力する時の文字が半角文字である場合は、「5文字で合わない時は4.5文字で折り返す」ルールに従い、次行の文字列の長さを0.5から始める
という処理を施すと所定の出力を得ることができ、この処理を実装している部分がawk '{len=$1==1?len+=0.5:len+=1;if(len<5){printf $2}else{print $2;len=$1==1?0.5:0}}'
となっています。
A9: 周期表のCSVファイルを作成
$ curl -s https://ja.wikipedia.org/wiki/%E5%91%A8%E6%9C%9F%E8%A1%A8 | sed '/id="周期表"/,/<\/center>/!d' | sed 's/<table /&border="1" /' | w3m -dump -T text/html | sed '/[A-Z]/!d' | sed 's/│/,/g;s/ //g;s/^,//;s/,$//;s/://' | sed 's/Ba,/&L/;s/Ra,/&A/;s/,La/L&/;s/,Ac/A&/' > PeriodicTable.csv
$ cat PeriodicTable.csv
H,,,,,,,,,,,,,,,,,He
Li,Be,,,,,,,,,,,B,C,N,O,F,Ne
Na,Mg,,,,,,,,,,,Al,Si,P,S,Cl,Ar
K,Ca,Sc,Ti,V,Cr,Mn,Fe,Co,Ni,Cu,Zn,Ga,Ge,As,Se,Br,Kr
Rb,Sr,Y,Zr,Nb,Mo,Tc,Ru,Rh,Pd,Ag,Cd,In,Sn,Sb,Te,I,Xe
Cs,Ba,L,Hf,Ta,W,Re,Os,Ir,Pt,Au,Hg,Tl,Pb,Bi,Po,At,Rn
Fr,Ra,A,Rf,Db,Sg,Bh,Hs,Mt,Ds,Rg,Cn,Nh,Fl,Mc,Lv,Ts,Og
L,La,Ce,Pr,Nd,Pm,Sm,Eu,Gd,Tb,Dy,Ho,Er,Tm,Yb,Lu
A,Ac,Th,Pa,U,Np,Pu,Am,Cm,Bk,Cf,Es,Fm,Md,No,Lr
この問題も、宿題として解いてみました。
端的にいうと、sed
の力技によるWebスクレイピングです。
LT大会
動画
rmコマンドチキンレース!
発表者: くんすと(@kunst1080)さん
カスタマイズしたrm
コマンドを使い、仮想マシンをジェンガに見立てて遊んでみようというLTです。
ただ遊ぶというだけでなく、どのファイルやディレクトリを削除するとシステムが壊れるのかを学ぶこともできます。
JavaScript製シューティングゲームをフルスクラッチで作ってみた
発表者: 日柳 光久(@mikkun_jp)
拙作のシューティングゲーム「EVADE AND DESTROY」の紹介です。
スマートフォンの片手持ちで遊べますので、暇つぶしにどうぞ。
ダブルシンク難読化シェル芸
発表者: たいちょー(@xztaityozx_001)さん
危険シェル芸をハフマン符号化して難読化を試みるというLTです。
なお、ここで使われているエンコード/デコード用コマンド「shellhuffman」はシェルスクリプトで書かれています。
サイゼリヤで学ぶシェル芸
発表者: so(@3socha)さん
$ echo ヤサイゼリ | grep -o . | shuf -r | head -5 | tr -d '\n'
ヤイゼヤサ
このワンライナーを何回実行すると「サイゼリヤ」と出力されるのかを計算する際に見舞われたトラブルとその解決法についてのLTです。
大きなデータを扱うシェル芸を実行する際には、SIGPIPE
の発生に気を付けたいものです。
sed ‘s/.*/sed計算機/’
発表者: いるやん(@Iruyan_Zak)さん
数値の計算が本来できないはずのsed
で足し算を行ってしまうという力作のワンライナーです。
$ echo '(+ 5 7)' | sed -E 's/\(\+ ([0-9]) ([0-9])\)/\1\2/;y/123456789/abcdefghi/;s/.$/\U&/;tadd;:add;s/(.)X/1\10/;s/(.?)0(.?)/\L\1\2/;tendadd;y/abcdefghiABCDEFGHI/0abcdefghBCDEFGHIX/;badd;:endadd;y/abcdefghi/123456789/'
12
……この発想は無かった。
感想など
タイトルに「朝からだと疲れるから午後からでええじゃろ」とは銘打たれていましたが、やはり疲れました。
LT大会については、参加人数8名に対しLT発表者が5名という活況ぶりで内容の方もあらゆる意味でスゴく、充実した時間を過ごすことができました。
20回くらいシェル芸勉強会で鍛えると、素人でもフルスクラッチでブラウザゲームを作り上げることができる程度にはなるということで(ありがたや > ALL)。
最後に、
- 大阪サテライトの主催をされている、くんすと(@kunst1080)さん、so(@3socha)さん
- 大阪サテライト会場を提供してくださっている、さくらインターネット株式会社 大阪本社様
- 上田隆一(@ryuichiueda)さんをはじめとする、メイン会場の講師およびスタッフの皆さん
に改めてお礼を申し上げます。ありがとうございました。