「第36回シェル芸勉強会:リモート参加」レポート
シェル芸勉強会に関するブログ記事の記載が滞っておりました。 シェル芸勉強会福岡サテライトの開催を予定していたのですが、大阪サテライトで大雨の影響で開催中止の連絡がありました。福岡は大丈夫か?と改めて大雨情報を確認するとありゃヤバイ・・・という事で、福岡サテライトも中止にしました。参加予定だった方々、もし良ければ次回に参加いただければ。
問題作成と解説の上田さん、ありがとうございます。参加者の方々もお疲れ様でした。
大雨の影響は想像以上で、甚大な災害の報道がありました。自然災害ややっぱり大変ですね。そもそも自分自身が帰宅難民になりかけてしまい・・・
twitter.comJR博多駅大混乱大混雑(;ω;)
— ぱぴろんちゃん😱🙀 (@papiron) 2018年7月6日
twitter.comJR九州の運行状況、下りは南福岡まで。南福岡より先は今日は運休。うええええええ(;ω;)
— ぱぴろんちゃん😱🙀 (@papiron) 2018年7月6日
twitter.comダメだ今日は帰宅出来そうにないわああああああああああああああああああああああ(;ω;)
— ぱぴろんちゃん😱🙀 (@papiron) 2018年7月6日
仕方ないので会社へ戻りちう(;ω;)
twitter.comJR九州のWebページ、運行状況情報が役に立って無いです(;ω;)
— ぱぴろんちゃん😱🙀 (@papiron) 2018年7月6日
twitter.comホテルはどこも満室なので、会社に泊まるしかなくなりました・・・ネットカフェもダメっぽい。あああああああああああああああああああああああああああああああああああああああああああああああああああああ
— ぱぴろんちゃん😱🙀 (@papiron) 2018年7月6日
twitter.com#福岡 #西鉄 が天神と二日市間で動き出したので、急遽電車に乗りました。やっとこさ帰宅出来そうですおおおおおおお!
— ぱぴろんちゃん😱🙀 (@papiron) 2018年7月6日
勉強会の情報
勉強会主催者上田さんが公開されているリンク集をご覧ください。
午前の部
午前の部は不参加。(第一第三土曜日の午前中は会議があるので調整が必要) 鳥海さんによる文字コードの話だったようだ。
午後の部
今回はボッチでYoutube見ながらリモート参加でした。
今回は参加者のフォローとかが無くて落ち着いた感じでしたが、問題解くのが難しいのは相変わらずです。 処理の内容は思いつくけど実現方法をどうするか?を思いつくのが大変たいへんタイヘンです。
Q1
テキストファイル内に隠されたメッセージを読み取る問題です!?
不可視文字を見つけろっていう事でしょうか??
バイナリデータ確認の定番として、まずはodコマンドで中身を確認してみます。
odコマンドの-t x1c
オプションは、不明なデータを見る時によく使います。
$ od -t x1c welcome.txt | head 0000000 5f 5f 5f 5f 5f 5f 5f 5f 5f 5f 5f 5f 5f 5f 5f 5f _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ * 0000060 00 5f 5f 00 5f 00 5f 5f 5f 5f 5f 5f 5f 5f 5f 5f \0 _ _ \0 _ \0 _ _ _ _ _ _ _ _ _ _ 0000100 5f 5f 5f 5f 5f 5f 5f 00 00 5f 5f 5f 5f 5f 5f 5f _ _ _ _ _ _ _ \0 \0 _ _ _ _ _ _ _
どうやらNUL文字が混入されているようです。という事でNUL文字を@
に変換してみます。
あとは折り返し文字幅80文字から10文字ずつ減らしながら試して、下記の通り解答完成です。
メッセージの作り方は上田さんの問題と解答のページをご覧ください。
$ cat welcome.txt | tr '\0' '@' | fold -w 70 | tr _ ' ' @ @ @ @@ @@@@@@ @@ @@@@@ @ @ @ @@ @@ @@@@@ @ @@@ @ @@@@@ @@@@@@@ @ @ @ @ @ @ @ @@@ @ @@ @ @@@ @@ @@@ @@ @@@@@ @@ @@@ @@@@@ @ @@ @ @ @@@ @ @ @@ @@@@@@ @@@@ @@@@ @@ @@@@@@@ @ @@ @ @@ @@ @@@ @@@@@ @@@ @ @@@ @@ @ @ @@ @@ @@@@ @ @@ @@@@ @@@@@ @@@@ @@ @@ @@ @ @ @@@@@@@ @@ @ @@@ @ @ @@ @ @ @ @ @ @@@ @@ @ @@@ @
Q2
悪質なファイル名を綺麗に整理する実用的な問題だそうです!? (こんなファイル名にするなあああああああああああああああとキレそうなやつ)
解答としては、下記のようなコマンドを実行すれば良いという事ですね。 このコマンドをどうやって作成実行するか考える問題です。
mv 1-B.doc 1年B組.doc mv 1A.doc 1年A組.doc mv 3年D組.doc 3年D組.doc ..(省略).. mv 1ーD.doc 1年D組.doc mv 1年E組.doc 1年E組.doc mv 4年C組.doc 4年C組.doc
Macで下記のように考えました。上記のようなコマンド列を出力します。
あとはパイプで| sh
に渡して実行すれば良いです。
# Mac限定。おそらくFreeBSDも可。 $ ls | tr '1-9' '1-9' | tr 'A-Z' 'A-Z' | tr 'a-z' 'A-Z' | sed 's/組\././' | sed 's/\([1-9]\)\(.\)\([A-Z]\)/\1\3/' | sed 's/\(.\)\(.\).*$/\1年\2組.doc/' | paste -d ' ' <(ls) - | sed 's/^/mv /'
しかし残念ながらUbuntuでは上記の解答は動きません。 GNUのtrコマンドはマルチバイト文字に非対応のようですね。
# GNUのtrコマンドは変になっちゃう $ ls | tr '1-9' '1-9' 1-B.doc 1A.doc 3999D99?.doc 399999999?.doc ..(省略)..
macOSやFreeBSD付属のtrコマンドやodコマンドは、マルチバイト文字対応しているので便利です。
Q3
これはまず日付の列挙をする必要があります。 方法は色々ありますが、seqコマンドとGNU dateを使ったやり方はこちらです。 まずは下記のような文字列リストを作成します。
$ seq 0 364 | sed 's/.*/20180101 & days/' 20180101 0 days 20180101 1 days 20180101 2 days ..(省略).. 20180101 362 days 20180101 363 days 20180101 364 days
次にGNU dateコマンドに-f -
オプションを付けてパイプで渡します。
$ seq 0 364 | sed 's/.*/20180101 & days/' | date -f - '+%Y%m%d' 20180101 20180102 20180103 ..(省略).. 20181229 20181230 20181231
あとは2,3,5,7が4つ含まれる行を抜き出せば良いです。 awkのgsubコマンドは、正規表現にマッチした回数を返すとのでこんな感じになります。 gsubコマンドは指定した文字列を破壊的に処理するので、$0の内容を変数dに代入して処理しています。
$ seq 0 364 | sed 's/.*/20180101 & days/' | date -f - '+%Y%m%d' | awk '{d=$0;if(gsub(/[2357]/,"",d)==4)print}' 20180222 20180223 20180225 ..(省略).. 20181223 20181225 20181227
Q4
俳句を考える問題!?というより縦書き処理をしろという問題です。まずは一句・・・
$ echo -e 'しぇるげいにん\nたなばたなのに\nひきこもり' しぇるげいにん たなばたなのに ひきこもり
ここから縦書きに変換していきます。
横書きを縦書きに変換する時は、行を上下ひっくり返した後、行列逆転すれば良いです。
という事でtac
からのrs -T
を使って処理することを考えます。
rs -T
を使う際は、データの数を縦横揃える必要があるので注意しましょう。
$ echo -e 'しぇるげいにん\nたなばたなのに\nひきこもり' | awk '{printf "%-7s\n",$0}' | sed 's/ /@/g' | sed 's/./& /g;s/ $//g' | tac | rs -T ひ た し き な ぇ こ ば る も た げ り な い @ の に @ に ん
あとは短冊に入れれば良いのですが、準備された短冊ファイルtanzakuを使ってないのでゴメンナサイ。
awkの$1=$1
の部分が意味不明に思う人が多いと思うので補足します。
OFSで出力の区切り文字を全角空白に指定していますが、これはフィールドの再構築を行わないと適用されません。
そこでパターン部分に$1=$1
のような処理を書いて、フィールドの再構築を明示的に指示しています。
$ echo -e 'しぇるげいにん\nたなばたなのに\nひきこもり' | awk '{printf "%-7s\n",$0}' | sed 's/ /@/g' | sed 's/./& /g;s/ $//g' | tac | rs -T | awk -vOFS=' ' 'BEGIN{print "┏ーー-┷-ーー┓"}$1=$1{print┃ "$0" ┃"}END{print "┗ーーーーーー┛"}' | sed 's/@/ /g' ┏ーー-┷-ーー┓ ┃ ひ た し ┃ ┃ き な ぇ ┃ ┃ こ ば る ┃ ┃ も た げ ┃ ┃ り な い ┃ ┃ の に ┃ ┃ に ん ┃ ┗ーーーーーー┛
Q5
えー下記のようにrevコマンドを単純に使ってもダメです。 文字列がひっくり返ってるし、馬の顔の輪郭もヘンテコリンになります。
$ cowsay あなたとJava今すぐダウンロード | rev ________________________________ > ドーロンウダぐす今avaJとたなあ < -------------------------------- ^__^ \ _______\)oo( \ \/\) \)__( | w----|| || ||
色々考えたけどどれも中途半端でダメでした。 出題者上田さんの解答例では、右側に文字を追加して各行の文字数を揃えた後でrevを使う方法でした。
Q6
素数のみを丸囲み文字にする問題。16進数に変換してxxdで処理とか考えたけど時間切れでした。
出題者上田さんの解答例以外では、下記の解答例がシンプルかなと思いました。
printfの出力フォーマットで%c
を使えばよいみたいです。
twitter.com前2つは全く歯が立たなかったけどこれはなんとか
— 新しいふぉるだ (@newfolderror) 2018年7月7日
seq 20 | factor | tr -d ":" | awk '$1==$2 { printf("%c\n", 9311+$1)} $1!=$2 {prin
t $1}'
#シェル芸
$ seq 20 | factor | tr -d ":" | awk '$1==$2 { printf("%c\n", 9311+$1)} $1!=$2 {print $1}' | xargs 1 ② ③ 4 ⑤ 6 ⑦ 8 9 10 ⑪ 12 ⑬ 14 15 16 ⑰ 18 ⑲ 20
Q7
テキストファイル内に隠された、謎のバイナリデータを探す問題。
下記はmacOSやFreeBSD限定の解答です。BSDのtrコマンドがマルチバイト文字に対応してるので。 あとnlコマンドの練習も兼ねて使ってみました。
$ cat text | tr -d '[:print:]' | cat -v | nl -ba 1 ^@ 2 3 4 5 ^B 6 7 8 ^F 9 10 ^V ..(省略)..
Q8
Sortware Designで連載中の「シェル芸人の挑戦状」から、更に上級問題でしたがギブアップ。 出題者上田さんの解答例は、mecabを使ってからの縦書きを横書きへ変換してからの・・・・という感じでした。
全体を通して
大雨によりサテライト会場が大阪・福岡共に開催出来なかったのは残念でしたね。 福岡サテライトの参加予定者は初めての方も多かったようなのですが、次回もし予定が合えばご参加よろしくお願いいたします。 福岡で独自に初心者向けを開催したいですが、プライベートやお仕事面で今は余裕が無く、なんとかしたいです。