第41回 シェル芸勉強会振り返り
第41回シェル芸勉強会に参加した。初参加です。
まえがき
2019/4/27 (土)に「jus共催 第41回{ウン,ガク,}{チ,ト,}{,ン}{,コイン}{ブ,}{ラブラ,
ハ,}{,イブ}{無,有}罪シェル芸勉強会」
に参加してきたのでその振り返り。
この名称自体もシェル芸で[ブレース展開]という記法。これをechoしてみると以下のよう
になる(※長すぎたので一部抜粋)。
echo jus共催 第41回{ウン,ガク,}{チ,ト,}{,ン}{,コイン}{ブ,}{ラブラ,ハ,}{,イブ}{無,有}罪シェル芸勉強会"\n" | wc -l
865
echo jus共催 第41回{ウン,ガク,}{チ,ト,}{,ン}{,コイン}{ブ,}{ラブラ,ハ,}{,イブ}{無,有}罪シェル芸勉強会"\n" | head
jus共催 第41回ウンチブラブラ無罪シェル芸勉強会
第41回ウンチブラブラ有罪シェル芸勉強会
第41回ウンチブラブライブ無罪シェル芸勉強会
第41回ウンチブラブライブ有罪シェル芸勉強会 +第41回ウンチブハ無罪シェル芸勉強会
第41回ウンチブハ有罪シェル芸勉強会
第41回ウンチブハイブ無罪シェル芸勉強会
第41回ウンチブハイブ有罪シェル芸勉強会
第41回ウンチブ無罪シェル芸勉強会
第41回ウンチブ有罪シェル芸勉強会
シェル芸勉強会の様子は Togetterにまとまっています。
午前の部
午後の部
8問のシェルの問題を片っ端からとくというもの。 問題に必要なファイルはこちらにある。 シェル芸のコマンドを実際に実行するなら、 あらかじめ以下のコマンドを実行して準備を整えておく。
git clone https://github.com/ryuichiueda/ShellGeiData cd ShellGeiData/vol.41
問題の一覧はこちら。 以降は問題と自分の回答。
Q1
Q.次のファイルについて、2列目をキーにしてエクセルの横列の記号(A, B, ..., Z, AA, AB, ...のやつ)順に並べ替えてください。
$ cat excel 114514 B 1192296 AA 593195 CEZ 4120 TZ 999 QQQ
回答としては、以下のように出力されてほしい。テストの意図としては、文字列の長さも 考慮してソートしてほしい、というもの。
114514 B 1192296 AA 4120 TZ 593195 CEZ 999 QQQ
普通に sort
コマンドで2カラム目を指定すると以下のようにソートされてしまう。
% sort -k2 excel 593195 AA 114514 B 1192296 CEZ 999 QQQ 4120 TZ
文字列の長さのカラムを追加してソートするのが正攻法だろう。 僕の回答としては以下の通り。
% awk '{print $0, length($2)}' excel | sort -k3 -k2 | cut -d ' ' -f 1,2 114514 B 593195 AA 4120 TZ 1192296 CEZ 999 QQQ
Q2
Q.次のファイルのレコードを干支順にソートしてください。
$ cat eto_yomi 申 さる 子 ね 寅 とら 卯 う 巳 み 辰 たつ 丑 うし 酉 とり 戌 いぬ 亥 い 午 うま 未 ひつじ
ただし、次のファイルを補助に使って良いこととします。
$ cat eto 子丑寅卯辰巳午未申酉戌亥
etoファイルの並びを利用してeto_yomiをソートするもの。まずは正攻法から。
sortなので素直にsortコマンドと別のファイルの中身を結合すると考えてjoinコマンドを 使用する。僕の回答としては以下の通り。
% grep -o . eto | nl | sort -k2 | join -1 2 -2 1 - <(sort eto_yomi) | sort -nk2 | cut -d ' ' -f 1,3 子 ね 丑 うし 寅 とら 卯 う 辰 たつ 巳 み 午 うま 未 ひつじ 申 さる 酉 とり 戌 いぬ
流れとしては下記の通り。
grep -o
で1行のデータを縦に並べてnl
で番号の列を追加- 後に控えている
join
は結合するフィールドが辞書順にソートされている必要がある ため、joinに指定するフィールドを辞書順にソート - joinで結合。
-1 2
と-2 1
で1個めのファイルの2フィールド目と2個めのファ イルの1フィールド目を結合する- eto_yomiも辞書順でソート
- 最初にnlで付与した番号を使い干支順にソートし直す
- cutで不要なフィールドの削除
シェル芸の非常に良いお題だったと思う。
次にgrepを使用した非常にコンパクトな例。初め僕は思いつかなかった。
% grep -o . eto | xargs -I@ grep @ eto_yomi 子 ね 丑 うし 寅 とら 卯 う 辰 たつ 巳 み 午 うま 未 ひつじ 申 さる 酉 とり 戌 いぬ 亥 い
すでに干支順でソートされているのでそのままgrepしてしまう、というもの。 こういうアプローチもあるのか、とまたシェル芸の知見が深まった。
Q3
Q.次のファイルのレコードを数字(第一フィールドの計算結果)が小さい順に並べてく ださい。
$ cat kim_calc 1+2+4 金正日 4*3 金正男 3-1-5 金日成 495/3 金正恩 0x1F 金正哲
これは割とすぐに思いついた。はじめは bc
コマンドを使用していたが0x1fで失敗する
のでbashの算術式を使用するようにしたら通った。
僕の回答としては下記の通り。
% cat kim_calc | while read -r e n; do echo $(($e)) $e $n; done | sort -nk1 | cut -d ' ' -f 2,3 3-1-5 金日成 1+2+4 金正日 4*3 金正男 0x1F 金正哲
Q4
Q.次のファイルはシフトJISのテキストですが、これを1) 辞書順、2) 数字の小さい順 、にソートしてください。出力もシフトJISとします。
$ cat sjis | nkf -g Shift_JIS $ cat sjis | nkf -wLux 123 ずんごるももう 31 こきたてひーひー 9 ほじぱんふんじこみ 2242 たまもとやろう
最初は試験の意図がわからなかったが、2つ結果を出力するだけでよかったらしい。 1の辞書順については下記の通り。
% cat sjis | nkf -wLux | sort 123 ずんごるももう 20 ほじぱんふんじこみ 2242 うえってきたかるとらまん 31 こきたてひーひー
2の数字の小さい順は手間が必要。このファイルの数値は全角数字なので数値ソートがで きない。なので修正してソートしてから復元する必要がある。僕の回答としては下記の通 り。
% cat sjis | nkf -wLux | sed 'y/1234567890/1234567890/' | sort -nk1 | sed 'y/1234567890/1234567890/' 20 ほじぱんふんじこみ 31 こきたてひーひー 123 ずんごるももう 2242 うえってきたかるとらまん
sedのyコマンドを使用して対応する数値を変換しているだけ。これも簡単な方だと思う。
Q5
Q.サイズの小さい順にソートしてください。
$ cat size 2GB 1.2GB 40000MB 1000000000kB 0.4GB 410MB
はじめはsortのヒューマンリーダブルオプションでいけるか、と思ったがダメだった。
% cat size | sort --sort h 1000000000kB 410MB 40000MB 0.4GB 1.2GB 2GB
なんとキロバイト順、メガバイト順、ギガバイト順にソートされている。 仕方なくnumfmtで変換して元に戻した。
% cat size | tr -d B | tr k K | numfmt --from iec --to=none | paste - size | sort -nk1 | cut -f2 0.4GB 410MB 1.2GB 2GB 40000MB
Q6
Q.sleepと内部コマンドだけを使って次の数を小さい順にソートしてください。
$ cat nums 5.4 0.34 2.3 0.9 6
これも割とすぐ思いついた。
内部コマンドってなんだろうと思ったが help
というコマンドを使えば分かる。
whileやforが使えたのと、非同期実行を使えば行ける。
% while read i; do (sleep $i; echo $i) & done < nums 0.34 0.9 2.3 5.4 6
Q7
Q.次のローマ数字をソートしてください。
$ cat roman IV XI LXXXIX IX XLIII XX VIII
これは割と力づくだったが一応いけた。
% cat ShellGeiData/vol.41/roman \ | sed 's/IV/4 /g;s/XL/40 /g;s/IX/9 /g;s/I/1 /g;s/L/50 /g;s/X/10 /g;s/V/5 /g;s/ /+/g;s/+$//g;s/.*/echo $((&))/e' \ | paste - ShellGeiData/vol.41/roman \ | sort -nk1 \ | cut -f 2 IV VIII IX XI XX XLIII LXXXIX
numconvというコマンドの存在を他の方のシェルから知った。 それを使えば以下のように修正できる。
% cat roman | numconv | paste - roman | sort -nk1 | cut -f2 IV VIII IX XI XX XLIII LXXXIX
Q8
Q.次のファイルを辞書順にソートしてください。ただし、濁点がついているものが先に 来るようにしてください。できる人はワンライナー中で「かきくけこがぎぐげご」の文 字を使わないでください。
$ cat gagigugego かき氷 ぎ・おなら吸い込み隊 きつねうどん ぐりこもりなが事件 きききりん がきの使い くその役にも立たない げんしりょく発電 ごりらいも こじんてきにはクソ 例 がきの使い かき氷 ぎ・おなら吸い込み隊 きききりん きつねうどん ぐりこもりなが事件 くその役にも立たない げんしりょく発電 ごりらいも こじんてきにはクソ
これははじめどうしたら良いかわからなかったが、午前の部で話していた内容を使えばす ぐに解決できることがわかった。濁点文字を濁点なしの文字と濁点の結合文字に分割する ことでソート順序を変更するというもの。
% cat ShellGeiData/vol.41/gagigugego | uconv -x NFD | sort | uconv -x NFC がきの使い かき氷 ぎ・おなら吸い込み隊 きききりん きつねうどん ぐりこもりなが事件 くその役にも立たない げんしりょく発電 ごりらいも こじんてきにはクソ
LT会
- https://github.com/agershun/alasql[AlaSQL]はJS製インメモリDB。SQL構文でデータ を操作できる
- https://github.com/itchyny/cam[cam]ターミナル上で画像が閲覧できる
- 上田さんとお会いできた
- Blacknonさんとお会いできた
- 僕はシェル芸うんこ派の人という認識らしい
まとめ
はじめてシェル芸勉強会に参加したけれど、新しい知見がいっぱいだった。 シェルはガリガリ普段から書いていたので、問題自体は割となんとかなった。 8問のうち7問は自力で解けた。解けなかったのはがぎぐげごのやつ。
何はともあれシェル芸勉強会、面白かった。 シェルはいろんな環境にあるし、ちょっとした作業をぱぱっと自動化できてやはり好きだし 今後も必要で有り続ける技術だと思うので、引き続き勉強は続けようと思う。
ただし100行を超えるような処理をシェルで書くのはやめよう。 素直に他の言語を使うべし(経験者は語る)。
以上。