起きるとそこは雪国だった。ここは福岡県。寒さに負けて引き篭もっていたいが、電車に乗るため駅へと向かうのであった。目的地はシェル芸勉強会の福岡サテライト会場。今回の会場はベータソフト様会議室を使わせていただいた。今回はのべ8人の有志がサムサニマケズ集った。
イベント関連ページ
本家東京会場募集
大阪サテライト会場募集
福岡サテライト会場募集
大阪サテライト会場レポート
Togetterまとめ
午前の部
参加者の方にsedの習熟度を聞いて見たのだが、それほど使い込んでいない方が多いようだ。そこで福岡サテライト会場では、午前の部を独自に進めることにした。午後からのsed問題に備えて、sedの基礎知識から中級編のネタについて話をした。
- GNU sedとBSD付属sed
1d;$d
などの行番号とdコマンドの組み合わせ-n
オプションで出力の抑止1,3
/<table/<\/table>/
などの範囲指定- yコマンドを使った変換とtrコマンドとの比較
echo 12345 | sed 's/^\(.\).*$/\2\1/'
のようなsコマンドの置換と後方参照find . -type f | sed 's;.*;cp -p & DIR;'
のような繰り返しコマンド列を作る技- 羊を100匹数えるコマンド列の作成(SoftwareDesignの記事)
- ラベルを使った繰り返し
- ホールドスペースを使ってtacコマンドの実装(行を逆順に)
sed p
の繰り返しで倍々ゲーム- sedでFizzBuzz
- Apacheログファイルの日時正規化
- その他シェル芸勉強会やTwitterで流れたsedの面白ネタ。
一通りsedの機能について話をした後、sedの元になったedの簡単なデモを行った。grepの名前の語源とコマンドについても説明した。(g/^1/p => g/正規表現/p => g/RE/p => grep
)
$ seq 10 > temp $ cat temp 1 2 3 4 5 6 7 8 9 10 $ ed temp 21 ## ファイルのバイト数表示 g/^1/p ## grepコマンドの名前の語源 ## 1 10 5p ## 5行目表示 5 1d ## 1行目削除 $d ## 最終行削除 w ## 保存 16 ## 保存後のファイルバイト表示 q ## ed終了 $ cat temp 2 3 4 5 6 7 8 9
sedのパターンスペースとホールドスペースの図解はこちらを参照のこと。 qiita.com
昼食
参加者みんなで近くの餃子の王将へ。途中で世界的に有名になった「博多の大穴」が出来ていた横断歩道を渡っていった。事故やけが人がいなかったのは本当に良かったと思う。
ここが世界的に有名になった「博多の大穴」が開いた場所。例のコンビニも。 #シェル芸 勉強会の会場近くです。 #博多 #福岡 pic.twitter.com/KVdasMpKWh
— ぱぴろんちゃん👓 (@papiron) 2017年2月11日
昼食を食べながら、仮想化やクラウド化が進み利便性が向上したが、教育という面では逆に難しくなった面もあるかもねーみたいなお話をした。抽象度が上がると入門者にとっては難解になってしまう面も否めないということ。なかなか難しい。
午後の部
午後の部が始まる前に、イントロのスライドで話をさせていただいた。言いたいことは一つ、勉強会に興味を持ってもらってありがたいということだ。
いよいよsed地獄?の始まりである。午前中にsedの話をしておいてよかった。話をしていなかったら参加者の大半が死亡していたことだろう・・・今回の問題と解答は下記を参照してほしい。
【問題と解答】第27回sedこわいシェル芸勉強会 – 上田ブログ
下記解答例はMacを使っているため、GNU sedはgsed
コマンドになっているので注意。Linuxの人はsed
に読み替えること。
Q1
一文字ずつ飛ばしてアルファベットを大文字に変換する問題。これは参加者の方から解答が出た。大文字へ変換する\U
に後方参照を組み合わせて\U\2
のようにすれば出来るとのこと。なるほど!会長の解答と同じである。
Q2
やっぱり出たか、sedでFizzBuzz。
### GNU sedで $ seq 100 | gsed '3~3s/$/ Fizz/' | gsed '5~5s/$/ Buzz/' | gsed '/z$/s/^[0-9]* //' 1 2 Fizz 4 Buzz Fizz 7 8 Fizz Buzz 11 Fizz 13 14 Fizz Buzz .... ### BSD sedで $ seq 20 | sed 'n;n;s/$/ Fizz/' | sed 'n;n;n;n;s/$/ Buzz/' | sed '/z$/s/^[0-9]* //' 1 2 Fizz 4 Buzz Fizz 7 8 Fizz Buzz 11 Fizz 13 14 Fizz Buzz .....
Q3
3行目を7行目の下に移動。下記のような解答を出したが、まあ会長の解答とほぼ同じ。今回の場合は最後の7g
は7x
でも良かった。
$ seq 10 | sed '3h;3d;7p;7g' 1 2 4 5 6 7 3 8 9 10
Q4
c++のソースファイルをコンパイル可能にしろというお題。関数宣言する前に関数を使ってるため、目的の関数をmain関数の前に移動しろということ。解答は会長と同じなので割愛。
Q5
2行ずつ入れ替えろというお題。参考のためsedを使わない解答を先に出しておいた。
$ seq 10 | xargs -n 2 | awk '{print $2,$1}' | xargs -n 1 2 1 4 3 6 5 8 7 10 9
次の行に移動するnコマンドやホールドスペースを使う必要がありそうだが、結局下記のようなのしか出来ずギブアップ。
$ seq 10 | sed 'h;n;G' 1 2 1 3 4 3 5 6 5 7 8 7 9 10 9
会長の解答を見たら、奇数行と偶数行で処理を分けて考えればいいみたいだ。
- 奇数行:ホールドスペースにコピーしてパターンスペースを削除
- 偶数行:ホールドスペースをパターンスペースに追記
会長が解答を更にシンプルしたものを出していたので下記に記載しておく。ホールドスペースをパターンスペースに追記する処理については、偶数行の指定は不要みたいだ。
$ seq 10 | gsed '1~2{h;d};G' 2 1 4 3 6 5 8 7 10 9
Q6
会長の解答とほぼ同じ。GNU sedのラベル機能を使った繰り返し処理。
$ echo 1 | gsed ':l;p;s/.$/&&/;tl' | head 1 11 111 1111 11111 111111 1111111 11111111 111111111 1111111111
上記はheadコマンドで強制的に10行ぶった切りしているが、会長の解答でラベルを使った繰り返し処理でb
コマンドを使うと繰り返し条件が書けるというのは勉強になった。これは便利そうである。
ちなみにラベルを使った繰り返しでt
コマンドも使える。これはs
コマンドを使った置換が成功する間繰り返す。詳しくはSoftware Design 2017年1月号のシェル特集で・・・
ちなみに上田会長によると、今回の勉強会がsed地獄になったきっかけは、上記Software Designの共同執筆中に起きた事件が元らしい。@ebanさんによるsedのラベルを使った繰り返し処理の解答が出てきて「ナンダコレワ??」と執筆陣の間で戦慄が走ったのであった・・・
Q7
縛り1の解答は会長と同じ。GNU sedのe
コマンドで解決。
縛り2の解答はギブアップ・・・10回の繰り返しを数字を使わず指定するにはheadコマンド使えば良さそうなのだが??でsedに行数を表示する=
というコマンドがあるということを知った。
Q8
上側半分を作るのはQ6と同じ。後半をどうするか?ラベルを2つ使ったループで解答した。
$ echo 1 | gsed ':LOOP1; p;s/.$/&&/;/.\{5\}/!bLOOP1;p; :LOOP2; p;s/.$//;/^.$/!bLOOP2' 1 11 111 1111 11111 11111 1111 111 11 1
考え方を変えると、前半の出力をひっくり返してケツに追加する問題。ということでsedのG
とh
コマンドを繰り返して、行を逆順にしていく技の応用になる。解答は会長の解答を参照のこと。
行順をひっくり返すtacコマンドの動きをsedでやる件については、大阪サテライト会場担当のid:kunst1080さん記事を参照のこと。 www.kunst1080.net
午後の部終了後
午後の部終了後、軽く問題のおさらいをしておいた。その後仮想端末のtmuxについて話をした。と言ってもまだ使い始めたばかりなのだが。
tmux起動時に自動的にWindow作成やpane分割、コマンド実行など出来るのか、確認したい。またコピーモードやスクロール操作がまだ理解出来ておらず。
今回は午前中にsedの話をしておいてよかった。話す内容をある程度まとめておいたので、スムーズに話が出来たと思う。福岡サテライト会場ではサポートが重要なので、今後も午前中はどういうやり方がいいか試行錯誤していこう。参加者の方々は、自分なりのペースで何かを掴んでいってもらえれば幸いである。そして少しずつでも輪が広がってサポートする側に回れるようになってもらえれば。