「あと5分で区切りますよー」の5分をカウントするシェルスクリプト
KPTのような全員で何かを書いて共有するタイプのミィーティングには「各々が書く」時間が存在する。[1]
その書く時間を計る時に、時計なりスマホのタイマー機能なり何なりで良いが、私がファシリテーションをしている時はシェルスクリプトで行うことがある。そういう趣味なので。
いくつかパターンがあるので紹介する。
環境
- MacBook, Monterey (だけどよほど古い OS でなければ関係ないと思う)
- zsh (だけど zsh の機能は使ってないと思う)
sleep + say
sleep 300 ; say -v Kyoko 'おわりだよ'
sleep
コマンドは指定した秒だけ待ってくれるので 300秒経ったら次のコマンドが実行される。
say
コマンドは文章を読み上げてくれる便利コマンドで、 -v Kyoko
とすることで日本語も読み上げてくれる。 -v Kyoko
にしないと英語で読み上げる。なので say 'time is up'
でもよい。
for + clear + echo
for i in {300..0}; do clear; echo $i; sleep 1; done
300 から 0 まで 1秒ずつカウントダウンして表示する。
clear
はターミナルの表示をお掃除するコマンドで、 echo
するたびに画面をまっさらにしてカウントダウンしてるっぽくする。
for が終わった後に say
コマンドで何か言わせてもよい。
nabeatsu
for i in {1..300}; do { echo $i | grep -o . ; factor $i; } | grep -q '\b3\b' && echo $i | sed 's/\(.\)..$/\1百 &/; s/.\{0,1\}\([^0]\)\(.\)$/\1十 &/; s/\(.*\) .*\(.\)$/\1 \2/; s/\([百十]\) 0/\1/; s/1\([百十]\)/\1/g; s/百/ヒャクwww/; s/十/ジュウwww/; s/1/イチwww/g; s/2/ニwww/g; s/3/サンwww/g; s/4$/シwww/; s/4/ヨンwww/g; s/5/ゴwww/g; s/6/ロクwww/g; s/7$/シチwww/; s/7/ナナwww/g; s/8/ハチwww/g; s/9/キュウwww/g' || echo $i; sleep 1; done
ただ数字がカウントダウンしているだけでは退屈な時はナベアツをする[2]。
解説
3の倍数は factor
コマンドで素因数分解した結果で判断する。
$ factor 123
123: 3 41
$ factor 123 | grep '\b3\b'
123: 3 41
$ factor 26 | grep '3' # '3' だと3がつく3以外の数も含むので \b が必要
26: 2 13
3がつくかどうかは grep
で判断する。
factor の結果とまとめて判断できるよう grep -o .
をしてから grep \b3\b
をする。
$ echo 123 | grep -o .
1
2
3
$ echo 123 | grep -o . | grep '\b3\b'
3
$ echo 123 | grep '\b3\b' # 3の前後に文字があるので検出されない
# factor の結果とまとめて判断
$ { echo 123 | grep -o . ; factor 123 ; }
1
2
3
123: 3 41
$ { echo 123 | grep -o . ; factor 123 ; } | grep -q '\b3\b'
$ echo $?
0
アホになる出力をするために数値を日本語に変換する。
111 を日本語で発音すると ヒャク ジュウ イチ となる。
百の位は3桁目に文字があるかどうかで判別できる。見つかったら百と書き込んでおく。
$ echo 123 | sed 's/\(.\)..$/\1百/'
1百
十の位も同じように2桁目に文字があるかどうかを見る。ただし 0 の時は日本語だと発音しないので無視する必要がある。[3]
$ echo 123 | sed 's/.\{0,1\}\([^0]\)\(.\)$/\1十/'
2十
百の位と十の位をまとめて抽出する。元の文字列をそのまま出力する &
を活用する。
$ echo 123 | sed 's/\(.\)..$/\1百 &/'
1百 123
$ echo 123 | sed 's/\(.\)..$/\1百 &/; s/.\{0,1\}\([^0]\)\(.\)$/\1十/'
1百 2十
# 十の位が 0 の時は無視する
$ echo 103 | sed 's/\(.\)..$/\1百 &/; s/.\{0,1\}\([^0]\)\(.\)$/\1十/'
1百 103
最後に一の位も抽出する。
一の位も十の位と同様に 0 の時は発音しないことに注意する。[4]
# & を使って一の位を抽出するための数値を用意
$ echo 123 | sed 's/\(.\)..$/\1百 &/; s/.\{0,1\}\([^0]\)\(.\)$/\1十 &/'
1百 2十 123
# 最後の一文字を抽出しつつ百の位や十の位の文字列も出力
$ echo 123 | sed 's/\(.\)..$/\1百 &/; s/.\{0,1\}\([^0]\)\(.\)$/\1十 &/;
s/\(.*\) .*\(.\)$/\1 \2/'
1百 2十 3
# 二桁以上の時で一の位が 0 の時は無視する処理を追加
$ echo 123 | sed 's/\(.\)..$/\1百 &/; s/.\{0,1\}\([^0]\)\(.\)$/\1十 &/;
s/\(.*\) .*\(.\)$/\1 \2/; s/\([百十]\) 0/\1/'
1百 2十 3
# 一の位が 0 の時は無視される
$ echo 120 | sed 's/\(.\)..$/\1百 &/; s/.\{0,1\}\([^0]\)\(.\)$/\1十 &/;
s/\(.*\) .*\(.\)$/\1 \2/; s/\([百十]\) 0/\1/'
1百 2十
百や十の位が1の時は数値は発音しないので取り除く。
$ echo 123 | sed 's/\(.\)..$/\1百 &/; s/.\{0,1\}\([^0]\)\(.\)$/\1十 &/;
s/\(.*\) .*\(.\)$/\1 \2/; s/\([百十]\) 0/\1/; s/1\([百十]\)/\1/g'
百 2十 3
日本語で発音する文字列に変換できたので、百は「ヒャクwww」といった具合にアホな発音に変換すればよい。
$ echo 123 | sed 's/\(.\)..$/\1百 &/; s/.\{0,1\}\([^0]\)\(.\)$/\1十 &/;
s/\(.*\) .*\(.\)$/\1 \2/; s/\([百十]\) 0/\1/; s/1\([百十]\)/\1/g;
s/百/ヒャクwww/; s/十/ジュウwww/; s/1/イチwww/g; s/2/ニwww/g; s/3/サンwww/g;
s/4$/シwww/; s/4/ヨンwww/g; s/5/ゴwww/g; s/6/ロクwww/g; s/7$/シチwww/;
s/7/ナナwww/g; s/8/ハチwww/g; s/9/キュウwww/g'
ヒャクwww ニwwwジュウwww サンwww
あとは3の倍数か3がつく数値かを判定する部分と組み合わせて for でループさせれば完成。
{ echo $i | grep -o . ; factor $i; } | grep -q '\b3\b'
が偽だった時はもとの数値をそのまま表示させるために || echo $i
を追加している。[5]
for i in {1..300}
do
{ echo $i | grep -o . ; factor $i; } | grep -q '\b3\b' && \
echo $i | sed 's/\(.\)..$/\1百 &/; s/.\{0,1\}\([^0]\)\(.\)$/\1十 &/;
s/\(.*\) .*\(.\)$/\1 \2/; s/\([百十]\) 0/\1/; s/1\([百十]\)/\1/g;
s/百/ヒャクwww/; s/十/ジュウwww/; s/1/イチwww/g; s/2/ニwww/g; s/3/サンwww/g;
s/4$/シwww/; s/4/ヨンwww/g; s/5/ゴwww/g; s/6/ロクwww/g; s/7$/シチwww/;
s/7/ナナwww/g; s/8/ハチwww/g; s/9/キュウwww/g' || echo $i
sleep 1
done
余談1
アホっぽい表現は 数え続ける世界のナベアツbot の方が好みです。バリエーション豊かです。
余談2
Ruby の humanize gem を使うともっと簡単に変換できます。
$ echo 123 | ruby -r'humanize' -ne 'puts $_.to_i.humanize(locale: :jp)'
百二十三
$ echo 123 | ruby -r'humanize' -ne 'puts $_.to_i.humanize(locale: :jp)' | sed 's/百/ヒャクwww/; s/十/ジュウwww/; s/一/イチwww/g; s/二/ニwww/g; s/三/サンwww/g; s/四$/シwww/; s/四/ヨンwww/g; s/五/ゴwww/g; s/六/ロクwww/g; s/七$/シチwww/; s/七/ナナwww/g; s/八/ハチwww/g; s/九/キュウwww/g'
ヒャクwwwニwwwジュウwwwサンwww
余談サンwww
nabeatsu コマンド を使えば一発です。[6]
$ nabeatsu 123
ヒャクニジュウサァンwww
余談4
この記事のタイトルは「ナベアツをシェルスクリプトで実装&解説する」が正しいかもしれない。
Discussion