第27回シェル芸勉強会へ遠隔参加
起きるとそこは雪国でした。ここは福岡県です。寒さに負けて引き篭もっていたい気持ちがありますが、電車に乗るため駅へと向かうのでした。目的地はシェル芸勉強会の福岡サテライト会場です。今回の会場はベータソフト様会議室を使わせていただきました。8人の参加者が集いました。 問題作成と解説の上田さん、ありがとうございます。参加者の皆様もお疲れ様でした。
勉強会の情報
勉強会主催者の上田さんが公開されているページをご覧ください。 b.ueda.tech
午前の部
参加者の方に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の話をしておいてよかったですね。
下記解答例はmacOSを使っているため、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のラベル機能を使った繰り返し処理です。
私の解答はt
コマンドで無限ループを使うので、headコマンドで強制的に10行に切り詰めています。
$ echo 1 | gsed ':l;p;s/.$/&&/;tl' | head 1 11 111 1111 11111 111111 1111111 11111111 111111111 1111111111
上田さんの解答では、b
コマンドで条件付き繰り返しを使っていました。これは便利そうですね。
詳しくは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の話をしておいてよかったです。話す内容をある程度まとめておいたので、ある程度スムーズに話が出来たとは思います。 福岡サテライト会場ではサポートが重要だと思うので、今後も午前中はどういうやり方がいいか試行錯誤していきたいと思います。 参加者の方々は、自分なりのペースで何かを掴んでいっていただけると幸いです。