「第32回シェル芸勉強会 大阪サテライト」の記録
イベント関連ページ
各会場の告知
レポート・まとめ
- jus共催 第32回全くインスタ映えしないシェル芸勉強会 | 上田ブログ
- 「第32回シェル芸勉強会:福岡サテライト」レポート - 日々之迷歩
- jus共催 第32回全くインスタ映えしないシェル芸勉強会 - Togetter
午前の部
講師
- 鳥海秀一(@hid_tori)さん/USP友の会
動画
資料
感想など
この勉強会の数日前から、オライリーのフクロウ本で予習らしきものをしていたものの、やはり難しい!!
マッチ時パターン展開やアトミックグループは、使いこなせればかなり便利そうなのですが、普段キャプチャ付き括弧程度しか使(?:わ|え)ない自分のような一般人にとっては、これらの高度な機能も宝の持ち腐れになってしまうのが悲しいところです。
……そもそもスライドに挙げられている変態Perlプログラマの解答例が何かの怪しい呪文にしか見えません。
午後の部
動画
問題・模範解答
解答
A1: 抜けた数字の行を飛ばして出力
当日は次のような解答
$ echo 14679 | grep -o . | awk '{n[NR]=$1}END{for(k in n){printf n[k]" ";for(i=n
[k];i<n[k+1];i++)printf i"\n"}}' | awk '{if(NR!=9){print $2?$1:" "}else{print $
1}}'
1
4
6
7
9
をツイートしましたが、今ひとつ美しくないということで
$ echo 14679 | grep -o . | diff -y - <(seq 9) | cut -f1
1
4
6
7
9
という別解を思い付きました。
これの手順は、
grep -o .
で1行1文字にする- 1.の出力と
seq 9
の出力を-y
オプションを付けたdiff
に与え、side-by-side形式(man diff
参照)で出力 cut -f1
で第1フィールドのみ出力
となっています。
A2: A1の空白行にa,b,c,…を埋める
$ echo 14679 | grep -o . | diff -y - <(seq 9) | cut -f1 | perl -nlE 'BEGIN{$c=97}{say $_?$_:chr($c++)}'
1
a
b
4
c
6
7
d
9
当日は解答できませんでしたが、A1の別解の発展形として解くことができました。
最後のperl -nlE 'BEGIN{$c=97}{say $_?$_:chr($c++)}'
で、空白行に対して小文字アルファベットを挿入しています。
なお、Perlの組み込み関数chr()
については、http://perldoc.jp/func/chrを参照して下さい。
A3: TCPのポート番号が素数のサービス一覧を作成
$ cat /etc/services | sed '/[0-9]\+\/tcp/!d' | sed 's|/.*||' | awk '{printf $1" ";system("factor "$2)}' | awk 'NF==3{print $3"\t"$1}' | sort -n
7 echo
11 systat
13 daytime
17 qotd
19 chargen
(...略...)
8081 tproxy
9103 bacula-sd
13721 bpdbm
20011 isdnlog
22273 wnn6
当日の解答が間違っていたので一からやり直しました。
手順としては、
sed
で「ポート番号/tcp」が含まれていない行を削除- 2回目の
sed
でサービス名とポート番号以外を削除 awk
のsystem()
関数で第2フィールドの値に対してfactor
を実行- 第2フィールドの値が素数の場合、行のフィールド数は3になるため、それに当てはまる行であれば「ポート番号・タブ・サービス名」の順に出力
sort -n
で数値順にソート
となっています。
A4: 並び替え
$ cat nums.txt
136
725
948
$ cat nums.txt | grep -o . | xargs | awk '{print $7$4$8$1$5$9$2$6$3}' | grep -o .
9
7
4
1
2
8
3
5
6
まだまだシェル芸力が低いので、
grep -o .
で1行1文字にするxargs
で各数字を空白区切りで1行に並べるawk
で並び替えgrep -o .
で再び1行1文字にする
という方法しか思い付きませんでした。
A5: ウムラウトを含む単語のみ抽出
$ cat umlaut.txt
wäschst wash 山田x Schrödinger
y上田 Ö アイウエオ unko
Übel Ärztin hoge カキクケコ
$ cat umlaut.txt | tr ' ' '\n' | perl -nlE 'say if /\xc3[\x84-\xb6]/'
wäschst
Schrödinger
Ö
Übel
Ärztin
ウムラウト記号が付いた文字のコードを調べると
$ cat umlaut.txt | grep -o . | LANG=C sed '/^..$/!d' | xxd -p | sed 's/0a/\n/g' | sort
c384
c396
c39c
c3a4
c3b6
のようになるので、
tr
で1行につき単語1ヶにするperl
で文字コードがc384からc3b6の範囲にある文字を含む行のみを出力
すればOKです。
A6: ツイッターアカウントの監視
$ getTweetNum(){ w3m -dump https://twitter.com/mikkun_jp 2>/dev/null | grep '^ • ツイートツイート、現在のページ。 [0-9,]\+$'; }; prev=$(getTweetNum); while :; do sleep 10; curr=$(getTweetNum); if [ "$prev" != "$curr" ]; then echo 'んほぉ!'; prev=$curr; fi; done
んほぉ!
関数getTweetNum()
で、ツイッターの特定のアカウントのWebページを取得し、ツイート数が記載されている行を抽出しています。
そして、この関数の中身を実行すると、次のような出力が得られます。
$ w3m -dump https://twitter.com/mikkun_jp 2>/dev/null | grep '^ • ツイートツイート、現在のページ。 [0-9,]\+$'
• ツイートツイート、現在のページ。 2,063
while
ループで10秒ごとにgetTweetNum()
を実行し、以前の実行結果と異なっていればメッセージを出力するようにします。
A7: ノイズ除去
$ cat image.txt
00010000000000001000000
00000000111111111110000
01111110011111111110001
00011110001111111111000
10011110001111111111000
00000001000000001000000
$ cat image.txt | sed 's/./ &/g' | awk '{for(i=1;i<=NF;i++){n[NR][i]=$i}}END{for(i=1;i<=NR;i++){for(j=1;j<=NF;j++){printf n[i-1][j]*n[i+1][j]*n[i][j-1]*n[i][j+1]==0?0:1;printf " "}printf "\n"}}' | awk '{for(i=1;i<=NF;i++){n[NR][i]=$i}}END{for(i=1;i<=NR;i++){for(j=1;j<=NF;j++){printf n[i-1][j]+n[i+1][j]+n[i][j-1]+n[i][j+1]>=1?1:0}printf "\n"}}'
00000000000000001000000
00000000001111111100000
00001100011111111110000
00011110001111111111000
00001100000111111110000
00000000000000001000000
問題文にある2つの条件
- ある数字について、上下左右の数字どれか1つに0が含まれる場合は0、そうでなければ1にする
- 次に、上下左右の数字どれか1つに1が含まれる場合は1、そうでなければ0にする
に従って、二次元配列が使えるプログラミング言語(この解答ではgawk
)で解いてみました。
A8: 漢字やカタカナが行頭に来るように改行
$ cat japanese.txt
ん僕らは既に死んでいる
死んでいるからシェル芸だ。
$ perl -C -nlE 's/(\p{Hiragana})([\p{Han}\p{Katakana}])/$1\n$2/g;say' japanese.txt
ん
僕らは
既に
死んでいる
死んでいるから
シェル芸だ。
Perlの正規表現では、「\p{…}
」(否定の場合は「\P{…}
」)といった、Unicodeのスクリプト(書記系)の名前による検索を利用できますので、任意のひらがな1文字と任意の漢字およびカタカナの間に改行が入るように置換を行い、出力しています。
LT大会
動画
- 第32回シェル芸勉強会 大阪サテライト LT 1/2 - YouTube
- 第32回シェル芸勉強会 大阪サテライト LT 2/2 - YouTube
- jus共催 第32回シェル芸勉強会 LT大会 - YouTube
diffとdiffのdiffを見る
発表者: くんすと(@kunst1080)さん
2つのdiff
のdiffを見るためのCLIツール、interdiff
についてのLTです。
動画でも挙げられていますが、このinterdiff
、元々は2つのパッチ間の差異を表示するツールということでGit rebase
の確認に便利そうです。
潜入工作任務用シェル芸
発表者: たいちょー(@xztaityozx_001)さん
「キーロガーに気づかれない危険シェル芸とは?」という、いささか不穏な空気が感じられますが、bash
の組み込みコマンドreadline
とbind
の使い方を学ぼうという至って真っ当なLTです。
AMAZON DASH HACK
発表者: MSR(@msr386)さん
dasherを利用して、AMAZON DASHをシェルコマンド実行用のボタンに改造してみようというLTです。
sed で始める簡単ループエンジン
発表者: いるやん(@Iruyan_Zak)さん
sed
を使ったシェル芸の実演です。🔃🍣楽しい!!🍣🔃
感想など
前回に引き続きパズル的要素の強い問題が多く出題されましたが、中にはQ6のWebページの監視やQ7のノイズ除去のような実用的?な問題もあり、パズルを解いていく楽しさとはまた一味違う楽しさもありました。
近頃は公私ともに多忙(年末進行+介護)で、文章を書くのも遅くなりがちですが、継続は力なりということでゆるゆるとマイペースでやっていこうと思っています。
最後に、
- 大阪サテライトの主催をされた、くんすと(@kunst1080)さん、小原一哉(@KoharaKazuya)さん
- 大阪サテライト会場を提供してくださった、フェンリル株式会社 大阪本社様
- 鳥海秀一(@hid_tori)さん、上田隆一(@ryuichiueda)さんをはじめとする、メイン会場の講師およ びスタッフの皆さん
に改めてお礼を申し上げます。ありがとうございました。
……それでは皆さん、良い年末年始を。