「第34回シェル芸勉強会」に参加しました

2018年3月17日に開催された「jus & USP友の会共催 シェル勉強会@関西(第34回いつも難しい問題ばっかり出す上田が真面目に考えた初心者用シェル芸勉強会)」に参加しました。

大阪でシェル芸勉強会が本会場として開催され、またUSP友の会・会長の上田隆一(@ryuichiueda)さんが勉強会の講師として大阪に来られたのは2014年6月以来ほぼ4年ぶりになります。

ちなみに、自分がシェル芸勉強会に初めて参加したのが丁度その時ということで、シェル芸を始めて約4年が経過したわけですが、データ処理やプログラミングの能力が始めた頃よりは多少なりとも上がったような気がします。ありがたいことです。


第1部:

資料:

動画(第1部〜LT大会):

第1部はコンピューティングにおけるファイルとは何か、という問いから始まりました。

そしてアプリケーションに縛られないテキストファイルの利便性を再び見直し、CLIコマンドの連携で効率良くデータを処理することができるということを話されました。

「楽しければ良い。便利ならなおさら良い。」そして「劣情に訴えない」。物事を他人に広める際に心しておきたい言葉です。


第2部:

問題:

A1:

$ cat /etc/services | awk '$2~/^80\/tcp/'
http		80/tcp		www		# WorldWideWeb HTTP
$ cat /etc/services | sed '/\t80\/tcp\t/!d'
http		80/tcp		www		# WorldWideWeb HTTP
$ cat /etc/services | awk '$2=="80/tcp"'
http		80/tcp		www		# WorldWideWeb HTTP
$ cat /etc/services | grep '[[:space:]]80/tcp[[:space:]]'
http		80/tcp		www		# WorldWideWeb HTTP

A2:

$ seq 10 | awk '{sum+=$1}END{print sum}'
55
$ seq 10 | sed -z 's/1\n/!/;s/2\n/!!/;s/3\n/!!!/;s/4\n/!!!!/;s/5\n/!!!!!/;s/6\n/!!!!!!/;s/7\n/!!!!!!!/;s/8\n/!!!!!!!!/;s/9\n/!!!!!!!!!/;s/10\n/!!!!!!!!!!/;s/./&\n/g' | sed '=;/!/d' | sed '$!d'
55

ちょっとトリッキーな、2つ目の解答を解説します。

まず、1回目のsedで各行の数字に対応した分量の「!」に置換します。

次に、2回目のsed=コマンドで行数を表示後、/!/dで「!」を削除します。

そして、最後のsedで最終行以外を削除すると「55」が出力されます。

A3:

$ echo '山田:003中村:002田代:001上田:004' | sed -r 's/.{6}/&\n/g;s/:/ /g;s/\n$//' | sort -k2,2n | sed -r 's/([^ ]+) ([^ ]+)/\2 \1/'
001 田代
002 中村
003 山田
004 上田

A4:

$ echo 0123456789 | nkf -Z
0123456789
$ echo 0123456789 | xxd -p | sed -r 's/(3|efbc9)([0-9])/\2/g;s/0a$//'
0123456789

文字列の16進ダンプを用いた2つ目の解答を説明します。

出題された文字列からxxdで16進ダンプを作成すると

$ echo 0123456789 | xxd -p
30efbc9132efbc9334efbc95363738efbc990a

のようになります。

半角数字の場合は「3」、全角数字の場合は「efbc9」が各数値の前に付いていますので、これらをsedで取り除きます。

そして、仕上げに末尾の改行「0a」を削除します。

A5:

$ echo '今日は、シェル芸の方から,きました.この消化器,買ってください。' | sed -r 's/(。|.)/./g;s/(、|,)/,/g;s/(\.|,)/& /g;s/ $//'
今日は, シェル芸の方から, きました. この消化器, 買ってください.

A6:

$ echo 'オッサンオバサンオッサンおっさんオバサンオバサンおばさんオバサンおばさん' | nkf -X --katakana | sed -r 's/.{4}/&\n/g' | awk '/オッサン/{M+=1}/オバサン/{F+=1}END{print "男:女\n"M":"F}'
男:女
3:6

A7:

$ w3m -dump 'http://www.post.japanpost.jp/cgi-zip/zipcode.php?pref=27' | grep '区' | sed 's/ .*//;s/^│//' | grep '大阪市' | grep -v '。' | sed 's/^大阪市//'
旭区
阿倍野区
生野区
北区
此花区
城東区
住之江区
住吉区
大正区
中央区
鶴見区
天王寺区
浪速区
西区
西成区
西淀川区
東住吉区
東成区
東淀川区
平野区
福島区
港区
都島区
淀川区

A8:

$ perl -E '@N=(1..9);@O=qw{+ - / *};for $a(@N){for $b(@O){for $c(@N){for $d(@O){for $e(@N){for $f(@O){for $g(@N){$F="$a$b$c$d$e$f$g";say $F if(eval "$F"==10)}}}}}}}'
1+1+1+7
1+1+1*8
1+1+2+6
1+1+2*4
1+1+3+5
1+1+4+4
1+1+4*2
1+1+5+3
1+1+6+2
1+1+7+1
(...略...)
9*6/3-8
9*6/6+1
9*6/9+4
9*7/7+1
9*7/9+3
9*8/4-8
9*8/6-2
9*8/8+1
9*8/9+2
9*9/9+1

通常のシェル芸勉強会で出題されるような高難度な問題です。

当日に解答することができませんでしたので、宿題としてperlで解いてみました。

bashのブレース展開を利用しても解くことができますが、文字列の生成に時間がかかるため、このようなケースではPerlワンライナーで解いたほうが楽だと思います。


LT大会:

WSLでシェル芸環境を整えてみた

WSL(Windows Subsystem for Linux)上で快適なシェル芸環境を構築するという内容です。

ちなみに、自分の作業環境はWSLではないのですが、tmuxでコマンドのマニュアルを見ながらシェル芸ができるのは本当に便利です。

AWKで動くへっぽこテトリスクローン / Tetris clone in AWK

拙作のテトリス風ゲーム「AWKTC」の紹介です。暇つぶしにどうぞ。

部活でシェル芸がはやらない

プログラミングを日常的に行っている人たちの間でも、シェル芸が受け入れられるのはなかなか難しいようで、シェル芸にまつわる情報交換の場としてこの勉強会が重要な位置を占めているという話です。

特に本職がIT関係ではない自分の場合は、シェル芸のみならずIT関連の情報を得る場がこの勉強会しかないので、シェル芸勉強会には感謝の限りです。


参考リンク:


Thanx:

Written on April 6, 2018