日々之迷歩

世の中わからんことだらけ

ITが複雑で難しくなっていく様に翻弄される日々です。微力ながら共著させていただいた「シェル・ワンライナー160本ノック」をよろしくお願い申し上げまする。

第27回シェル芸勉強会へ遠隔参加

起きるとそこは雪国だった。ここは福岡県。寒さに負けて引き篭もっていたいが、電車に乗るため駅へと向かうのであった。目的地はシェル芸勉強会の福岡サテライト会場。今回の会場はベータソフト様会議室を使わせていただいた。今回はのべ8人の有志がサムサニマケズ集った。

sites.google.com

イベント関連ページ

本家東京会場募集

usptomo.doorkeeper.jp

大阪サテライト会場募集

atnd.org

福岡サテライト会場募集

atnd.org

大阪サテライト会場レポート

www.kunst1080.net

Togetterまとめ

togetter.com

午前の部

参加者の方に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

昼食

参加者みんなで近くの餃子の王将へ。途中で世界的に有名になった「博多の大穴」が出来ていた横断歩道を渡っていった。事故やけが人がいなかったのは本当に良かったと思う。

昼食を食べながら、仮想化やクラウド化が進み利便性が向上したが、教育という面では逆に難しくなった面もあるかもねーみたいなお話をした。抽象度が上がると入門者にとっては難解になってしまう面も否めないということ。なかなか難しい。

午後の部

午後の部が始まる前に、イントロのスライドで話をさせていただいた。言いたいことは一つ、勉強会に興味を持ってもらってありがたいということだ。

speakerdeck.com

いよいよ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行目の下に移動。下記のような解答を出したが、まあ会長の解答とほぼ同じ。今回の場合は最後の7g7xでも良かった。

$ 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のGhコマンドを繰り返して、行を逆順にしていく技の応用になる。解答は会長の解答を参照のこと。

行順をひっくり返すtacコマンドの動きをsedでやる件については、大阪サテライト会場担当のid:kunst1080さん記事を参照のこと。 www.kunst1080.net

午後の部終了後

午後の部終了後、軽く問題のおさらいをしておいた。その後仮想端末のtmuxについて話をした。と言ってもまだ使い始めたばかりなのだが。

speakerdeck.com

tmux起動時に自動的にWindow作成やpane分割、コマンド実行など出来るのか、確認したい。またコピーモードやスクロール操作がまだ理解出来ておらず。

今回は午前中にsedの話をしておいてよかった。話す内容をある程度まとめておいたので、スムーズに話が出来たと思う。福岡サテライト会場ではサポートが重要なので、今後も午前中はどういうやり方がいいか試行錯誤していこう。参加者の方々は、自分なりのペースで何かを掴んでいってもらえれば幸いである。そして少しずつでも輪が広がってサポートする側に回れるようになってもらえれば。