2016年6月20日

第23回シェル芸勉強会参加報告

2016-06-18(土)に開催された、第23回シェル芸勉強会(正式名称:jus共催、第5回初心者向けとは言うものの午前のシェル勉強会/第23回梅雨でモワッとしたシェル芸勉強会)に参加しました。
ただ、在住地の関係で直接会場へ伺うことは出来なかったため、Youtubeで配信してくださったライブ中継を利用して、遠隔で参加しました。

勉強会は、午前と午後の2部構成でした。
午前は、シェルに関する勉強会で、FreeBSDのブートプロセスの解説と、シェル芸入門という内容でした。
午後は、シェル芸勉強会で、シェル芸力を付けるための問題を解きました。

以下、勉強会の詳細を記します。


実行環境

  • Arch Linux (x86_64, 4.6.2-1-ARCH)

  • bash (4.3.42)

  • GNU coreutils (8.25)

  • gawk (4.1.3)

  • curl (7.49.1)

  • nkf (2.1.4)


シェルに関する勉強会

FreeBSDのブートプロセス

USP友の会 今泉 光之(@bsdhack)さんによる、FreeBSDのブートプロセスを学ぶ内容でした。
…​が、諸事情により参加できずorz

シェル芸入門

USP友の会 石井 久治(@hisaharu)さんによる、シェル芸入門という内容でした。
…​が、こちらも同様に参加できずorz
ちなみに、毎回 初心者向けという名の上級者向け な内容が多い午前中の勉強会ですが、石井さんによるこのシェル芸入門は、 本当の意味で入門編 だったそうです!

第23回シェル芸勉強会

復習も兼ねて、コードを手直し&コメントを付加したうえで掲載します。
今回は、usp Tukubaiを利用したものの、Tukubaiを利用しないものの、2種類の解答を記載します。
また、今回の解答では、 各コマンドを実行した際のフィールド構成の変化 を、強く意識することにします。

問題文および解答は、以下のURLから。
https://blog.ueda.asia/?p=8381

前準備

今回の問題はオープンデータを用いた。
そのため、問題を解く際に必要となるデータを、予め準備しておく。
必要なデータは、次の2つ。

問1~5用

気象庁が公開している、「毎月の台風の上陸数」のデータ。

curl http://www.data.jma.go.jp/fcd/yoho/typhoon/statistics/landing/landing.csv | nkf -wLux > landing.csv

問6~9用

大阪市が公開している、「平成27年 大阪市の犯罪発生情報 ひったくり」のデータ。

curl http://www.city.osaka.lg.jp/shimin/cmsfiles/contents/0000298/298810/006hittakuri2015.csv | nkf -wLux | tr , ' ' | tail -n +2 > hittakuri

問1

取得した台風の上陸数データを、各レコードにつき"年月 上陸数"の形式に整形する問題。

Tukubai無し版。この問題は、Tukubaiを使わなかった。

01  #!/bin/sh
02
03  cat landing.csv \
04  | # 元データの出力
05    ### 1:年 2~13:上陸回数(各月毎) 14:上陸回数(年間合計)
06  sed '1d' \
07  | # ヘッダの除去
08  awk -F, '{for(i=2;i<=NF-1;i++){printf("%d%.2d %d\n", $1,i-1,$i)}}' > monthly_typhoon
09    # 年月毎に回数を集計
10    ### 1:年月 2:上陸回数(年月毎)

変哲もない、素直な問題。
不要なヘッダを除去した後、awkで集計していくだけ。

以下、コピペ実行用のワンライナーコード。

cat landing.csv | sed '1d' | awk -F, '{for(i=2;i<=NF-1;i++){printf("%d%.2d %d\n", $1,i-1,$i)}}' > monthly_typhoon

問2

問1で作成したmonthly_typhoonのファイルを用いて、年毎の上陸頻度を集計する問題。

まずはTukubai版。

01  #!/bin/sh
02
03  cat monthly_typhoon \
04  | # 元データの出力
05    ### 1:年月 2:上陸回数(年月毎)
06  sed 's/^\([[:digit:]]\{4\}\)[[:digit:]]\{2\}/\1/' \
07  | # 第一フィールドをYYYYに整形
08    ### 1:年 2:上陸回数(年月毎)
09  sm2 1 1 2 2
10    # 第一フィールドをキーとして集計
11    ### 1:年 2:上陸回数(年毎)

そしてTukubai無し版。

01  #!/bin/sh
02
03  cat monthly_typhoon \
04  | # 元データの出力
05    ### 1:年月 2:上陸回数(年月毎)
06  sed 's/^\([[:digit:]]\{4\}\)[[:digit:]]\{2\}/\1/' \
07  | # 第一フィールドをYYYYに整形
08    ### 1:年 2:上陸回数(年月毎)
09  awk '{year[$1]+=$2} END{for(i in year){print i,year[i]}}'
10    # 第一フィールドをキーとして集計
11    ### 1:年 2:上陸回数(年毎)

これも素直な問題。
元データは「年月」毎に集計されているため、これを「年」毎のデータにする。
単純に第一フィールドの後ろ二文字を削ってやれば、「年」毎のデータに整形できる。
最後に、sm2なりawkなりを用いて、「年」をキーとして上陸回数を集計してやるだけ。

以下、コピペ実行用のワンライナーコード。
Tukubai版。

cat monthly_typhoon | sed 's/^\([[:digit:]]\{4\}\)[[:digit:]]\{2\}/\1/' | sm2 1 1 2 2

Tukubai無し版。

cat monthly_typhoon | sed 's/^\([[:digit:]]\{4\}\)[[:digit:]]\{2\}/\1/' | awk '{year[$1]+=$2} END{for(i in year){print i,year[i]}}'

問3

各月に台風が上陸する確率を求める問題。

実はこの問題、当日に正答を出せなかった…​
当日の解答を整形したやつ。

01  #!/bin/sh
02
03  cat monthly_typhoon \
04  | # 元データの出力
05    ### 1:年月 2:上陸回数(年月毎)
06  sed 's/^[[:digit:]]\{4\}//' \
07  | # 第一フィールドをMMに整形
08    ### 1:月 2:上陸回数(年月毎)
09  sort \
10  | # データのソート
11  sm2 1 1 2 2 \
12  | # 第一フィールドをキーとして第二フィールドの集計
13    ### 1:月 2:上陸回数(月毎)
14  ratio key=2
15    # 各月の上陸確率を出力...したつもり(実際は構成比率を出力しているだけorz)
16    ### 1:月 2:上陸回数(月毎) 3:構成比率

そして正答。この問題も、正答ではTukubaiを使わなかった。

01  #!/bin/sh
02
03  cat monthly_typhoon \
04  | # 元データの出力
05    ### 1:年月 2:上陸回数(年月毎)
06  sed 's/^[[:digit:]]\{4\}//' \
07  | # 第一フィールドをMMに整形
08    ### 1:月 2:上陸回数(年月毎)
09  awk '$2!=0{prob_t[$1]++} $2==0{prob_f[$1]++} END{for(i in prob_f){print i,prob_t[i]/(prob_t[i]+prob_f[i])}}' \
10  | # 月ごとの上陸確率の算出
11    ### 1:月 2:上陸確率
12  sort
13    # 算出結果のソート

個人的に、今回の勉強会で一番難しかった問題…​
というのも、自分では確率を求めているつもりだったけれど、実は各月の上陸回数について、 構成比率 を求めているだけだったorz
どうも他の方と同じ出力にならないなぁ…​と思いつつ、けっきょく勉強会後に初めて間違いに気付くことに(^_^;)

以下、コピペ実行用のワンライナーコード。

誤答版。

cat monthly_typhoon | sed 's/^[[:digit:]]\{4\}//' | sort | sm2 1 1 2 2 | ratio key=2

正答版。

cat monthly_typhoon | sed 's/^[[:digit:]]\{4\}//' | awk '$2!=0{prob_t[$1]++} $2==0{prob_f[$1]++} END{for(i in prob_f){print i,prob_t[i]/(prob_t[i]+prob_f[i])}}' | sort

問4

各年で最初に台風が上陸した月を抽出し、各月毎の上陸回数を集計する問題。

まずはTukubai版。

01  #!/bin/sh
02
03  cat monthly_typhoon \
04  | # 元データの出力
05    ### 1:年月 2:上陸回数(年月毎)
06  sed 's/^[[:digit:]]\{4\}/& /' \
07  | # 第一フィールドを2つのフィールドに分割
08    ### 1:年 2:月 3:上陸回数(年月毎)
09  awk '$3!=0' \
10  | # 台風が上陸したレコードの抽出
11  getfirst 1 1 \
12  | # 各年における台風が初めに上陸した月レコードの抽出
13  self 2 \
14  | # 第二フィールドの抽出
15    ### 1:月
16  sort -n \
17  | # 数値順にソート
18  count 1 1
19    # 月毎に回数を集計
20    ### 1:月 2:上陸回数(月毎)

そしてTukubai無し版。

01  #!/bin/sh
02
03  cat monthly_typhoon \
04  | # 元データの出力
05    ### 1:年月 2:上陸回数(年月毎)
06  sed 's/^[[:digit:]]\{4\}/& /' \
07  | # 第一フィールドを2つのフィールドに分割
08    ### 1:年 2:月 3:上陸回数(年月毎)
09  awk '$3!=0' \
10  | # 台風が上陸したレコードの抽出
11  awk '$0=$2" "$1' \
12  | # 第三フィールドの削除および第一フィールドと第二フィールドの入替
13    ### 1:月 2:年
14  uniq -f 1 \
15  | # 各年における台風が初めて上陸した月レコードの抽出
16  awk '{month[$1]++} END{for(i in month){print i,month[i]}}' \
17  | # 月毎に回数を集計
18    ### 1:月 2:上陸回数(月毎)
19  sort
20    # 出力のソート

Tukubaiを使うと、けっこうシンプル!
Tukubaiを使わない方法でも、やっている事は大体同じ。
14行目のuniqで、年毎の初めて上陸したレコードを抽出するために、Tukubaiとはフィールドの構成を逆にしている。

以下、コピペ実行用のワンライナーコード。

Tukubai版。

cat monthly_typhoon | sed 's/^[[:digit:]]\{4\}/& /' | awk '$3!=0' | getfirst 1 1 | self 2 | sort -n | count 1 1

Tukubai無し版。

cat monthly_typhoon | sed 's/^[[:digit:]]\{4\}/& /' | awk '$3!=0' | awk '$0=$2" "$1' | uniq -f 1 | awk '{month[$1]++} END{for(i in month){print i,month[i]}}' | sort

問5

台風が上陸しなかった年を抽出する問題。

まずはTukubai版。当日の解答とほぼ同じ。

01  #!/bin/sh
02
03  cat monthly_typhoon \
04  | # 元データの出力
05    ### 1:年月 2:上陸回数(年月毎)
06  sed 's/^[[:digit:]]\{4\}/& /' \
07  | # 第一フィールドを2つのフィールドに分割
08    ### 1:年 2:月 3:上陸回数(年月毎)
09  delf 2 \
10  | # 第二フィールドの削除
11    ### 1:年 2:上陸回数(年月毎)
12  sm2 1 1 2 2 \
13  | # 第一フィールドをキーとして集計
14    ### 1:年 2:上陸回数(年毎)
15  awk '$2==0 && $0=$1'
16    # 集計数が0(台風が上陸しなかった)のレコードの出力
17    ### 1:年

そしてTukubai無し版。

01  l#!/bin/sh
02
03  cat monthly_typhoon \
04  | # 元データの出力
05    ### 1:年月 2:上陸回数(年月毎)
06  sed 's/^[[:digit:]]\{4\}/& /' \
07  | # 第一フィールドを2つのフィールドに分割
08    ### 1:年 2:月 3:上陸回数(年月毎)
09  awk '$3==0' \
10  | # 台風が上陸しなかった月の抽出
11  awk '$0=$1' \
12  | # 第一フィールドのみを出力
13    ### 1:年
14  uniq -c \
15  | # 第一フィールドをキーとしてレコード数を集計
16    ### 1:上陸回数(年毎) 2:年
17  awk '$1==12 && $0=$2'
18    # 集計数が12ヶ月(=一度も上陸していない)の年の出力
19    ### 1:年

この問題もシンプル。
とはいえ、Tukubaiを使わない版だと、「同じレコードが12個ある」と逆転の発想をする必要があるので、少しややこしいかも。

以下、コピペ実行用のワンライナーコード。

Tukubai版。

cat monthly_typhoon | sed 's/^[[:digit:]]\{4\}/& /' | delf 2 | sm2 1 1 2 2 | awk '$2==0 && $0=$1'

Tukubai無し版。

cat monthly_typhoon | sed 's/^[[:digit:]]\{4\}/& /' | awk '$3==0' | awk '$0=$1' | uniq -c | awk '$1==12 && $0=$2'

問6

ここからは別のデータを使う。
大阪市の各区毎に、ひったくりが何件発生したのかを集計する問題。

まずはTukubai版。

01  #!/bin/sh
02
03  cat hittakuri  \
04  | # 元データの出力
05    ### 1:地区 2:町 3:区域 4:犯罪大種別 5:成否 6:犯罪小種別 7:実行手段 8:年 9:月 10:日 11:時 12:性別 13:年代
06  sort -k 1,1 \
07  | # 第一フィールドをキーとしてソート
08  count 1 1
09    # 第一フィールドをキーとしてレコード数を集計
10    ### 1:地区 2:発生件数

そしてTukubai無し版。

01  #!/bin/sh
02
03  cat hittakuri  \
04  | # 元データの出力
05    ### 1:地区 2:町 3:区域 4:犯罪大種別 5:成否 6:犯罪小種別 7:実行手段 8:年 9:月 10:日 11:時 12:性別 13:年代
06  awk '{dist[$1]++} END{for(i in dist){print i,dist[i]}}'
07    # 第一フィールドをキーとしてレコード数を集計
08    ### 1:地区 2:発生件数

これまたシンプルな問題。
第一フィールドが「区名」なので、これをキーとして集計するだけ。
ただ、Tukubaiのcountを用いる場合、予めソートする必要がある点に注意。

以下、コピペ実行用のワンライナーコード。

Tukubai版。

cat hittakuri  | sort -k 1,1 | count 1 1

Tukubai無し版。

cat hittakuri  | awk '{dist[$1]++} END{for(i in dist){print i,dist[i]}}'

問7

各区の人口データ"pupulation_h27sep"を併用して、各区の人口あたりのひったくり件数ランキングを求める問題。

まずはTukubai版。

01  #!/bin/bash
02
03  join \
04  <( \
05      cat hittakuri \
06      | # ひったくりデータの出力
07        ### 1:地区 2:町 3:区域 4:犯罪大種別 5:成否 6:犯罪小種別 7:実行手段 8:年 9:月 10:日 11:時 12:性別 13:年代
08      sort -k 1,1 \
09      | # 第一フィールドをキーとしてソート
10      awk '{dist[$1]++} END{for(i in dist){print i,dist[i]}}' \
11      | # 第一フィールドをキーとしてレコード数を集計
12        ### 1:地区 2:件数
13      sort \
14        # 集計結果のソート
15  ) \
16  <( \
17      cat population_h27sep \
18      | # 人口データの出力
19        ### 1:地区 2:人口数
20      sort
21        # 人口データのソート
22  ) \
23  | # ひったくり件数と人口データの結合
24    ### 1:地区 2:件数 3:人口数
25  awk '{printf("%s %f\n", $1,$2/$3)}' \
26  | # 各区あたりのひったくり件数の構成比率の出力
27    ### 1:地区 2:構成比率
28  sort -k 2,2nr \
29  | # 構成比率をキーとして降順数値ソート
30  delf 2 \
31  | # 第二フィールドの除去
32    ### 1:地区
33  juni
34    # 順位の出力
35    ### 1:順位 2:地区

そしてTukubai無し版。最後の2つのコマンド以外は、全く同じ。

01  #!/bin/bash
02
03  join \
04  <( \
05      cat hittakuri \
06      | # ひったくりデータの出力
07        ### 1:地区 2:町 3:区域 4:犯罪大種別 5:成否 6:犯罪小種別 7:実行手段 8:年 9:月 10:日 11:時 12:性別 13:年代
08      sort -k 1,1 \
09      | # 第一フィールドをキーとしてソート
10      awk '{dist[$1]++} END{for(i in dist){print i,dist[i]}}' \
11      | # 第一フィールドをキーとしてレコード数を集計
12        ### 1:地区 2:件数
13      sort \
14        # 集計結果のソート
15  ) \
16  <( \
17      cat population_h27sep \
18      | # 人口データの出力
19        ### 1:地区 2:人口数
20      sort
21        # 人口データのソート
22  ) \
23  | # ひったくり件数と人口データの結合
24    ### 1:地区 2:件数 3:人口数
25  awk '{printf("%s %f\n", $1,$2/$3)}' \
26  | # 各区あたりのひったくり件数の構成比率の出力
27    ### 1:地区 2:構成比率
28  sort -k 2,2nr \
29  | # 構成比率をキーとして降順数値ソート
30  awk '$0=$1' \
31  | # 第二フィールドの除去
32    ### 1:地区
33  nl
34    # 順位の出力
35    ### 1:順位 2:地区

何だか複雑な事をしている…​ように見えて、実はあまり大したことはしていなかったり。
"地区 発生件数"と"地区 人口数"の2つのデータを用意して、joinコマンドで結合する。
その後、各区あたりの構成比率を求めて、ランキング化するだけ。
bashのプロセス置換を利用しているので、ちょっと読み辛くなってしまったのが残念…​
てか、この問題は、Tukubaiを使う意味が無かったかも…​

以下、コピペ実行用のワンライナーコード。

Tukubai版。

join <(cat hittakuri | sort -k 1,1 | awk '{dist[$1]++} END{for(i in dist){print i,dist[i]}}' | sort) <(cat population_h27sep | sort) | awk '{printf("%s %f\n", $1,$2/$3)}' | sort -k 2,2nr | delf 2 | juni

Tukubai無し版。

join <(cat hittakuri | sort -k 1,1 | awk '{dist[$1]++} END{for(i in dist){print i,dist[i]}}' | sort) <(cat population_h27sep | sort) | awk '{printf("%s %f\n", $1,$2/$3)}' | sort -k 2,2nr | awk '$0=$1' | nl

問8

同一住所で同日に2件以上のひったくりが発生しているデータの、住所と日付を求める問題。

まずはTukubai版。

01  #!/bin/sh
02
03  cat hittakuri \
04  | # 元データの出力
05    ### 1:地区 2:町 3:区域 4:犯罪大種別 5:成否 6:犯罪小種別 7:実行手段 8:年 9:月 10:日 11:時 12:性別 13:年代
06  self 1/3 8/10 \
07  | # 発生箇所および日付フィールドの抽出
08    ### 1:地区 2:町 3:区域 4:年 5:月 6:日
09  awk '$0=$1$2$3" "$4$5$6' \
10  | # フィールド数を2つに整形
11    ### 1:地区町区域 2:年月日
12  sort \
13  | # データのソート
14  uniq -d
15    # 重複のある(同じ日に2件以上発生している)レコードの抽出

そしてTukubai無し版。

01  #!/bin/sh
02
03  cat hittakuri \
04  | # 元データの出力
05    ### 1:地区 2:町 3:区域 4:犯罪大種別 5:成否 6:犯罪小種別 7:実行手段 8:年 9:月 10:日 11:時 12:性別 13:年代
06  awk '{print $1,$2,$3,$8,$9,$10}' \
07  | # 発生箇所および日付フィールドの抽出
08    ### 1:地区 2:町 3:区域 4:年 5:月 6:日
09  awk '$0=$1$2$3" "$4$5$6' \
10  | # フィールド数を2つに整形
11    ### 1:地区町区域 2:年月日
12  sort \
13  | # データのソート
14  uniq -d
15    # 重複のある(同じ日に2件以上発生している)レコードの抽出

この問題のポイントは、「同じ内容が2行以上あるものだけを出力する」、uniqコマンドの"-d"オプション。
これさえ思い出せれば、簡単に出力できる。
もし思い出せなかった場合でも、awkの連想配列等でも代用できるはず。
また、uniqを実行する前に、sortを忘れずに。
てか、この問題もTukubaiを使う意味があまり無かった…​orz

以下、コピペ実行用のワンライナーコード。

Tukubai版。

cat hittakuri | self 1/3 8/10 | awk '$0=$1$2$3" "$4$5$6' | sort | uniq -d

Tukubai無し版。

cat hittakuri | awk '{print $1,$2,$3,$8,$9,$10}' | awk '$0=$1$2$3" "$4$5$6' | sort | uniq -d

問9

ラスト。ひったくりの手段とその成功率を求める問題。

まずはTukubai版。

01  #!/bin/sh
02
03  cat hittakuri \
04  | # 元データの出力
05    ### 1:地区 2:町 3:区域 4:犯罪大種別 5:成否 6:犯罪小種別 7:実行手段 8:年 9:月 10:日 11:時 12:性別 13:年代
06  self 7 5 \
07  | # 第七・第五フィールドの抽出
08    ### 1:実行手段 2:成否
09  sort -k 1,1 \
10  | # 第一フィールドをキーとしてソート
11  count 1 2 \
12  | # 第一フィールドをキーとして第二フィールドのレコード数を集計
13    ### 1:実行手段 2:成否 3:観測数
14  delf 2 \
15  | # 不要な第二フィールドの除去
16    ### 1:実行手段 2:観測数
17  yarr num=1 \
18  | # 第一フィールドをキーとして第二フィールドを横展開
19    ### 1:実行手段 2:成功数 3:失敗数
20  awk '{print $1,$2/($2+$3)}'
21    # 各レコード毎の成功率を算出
22    ### 1:実行手段 2:成功率

そしてTukubai無し版。

01  #!/bin/sh
02
03  cat hittakuri \
04  | # 元データの出力
05    ### 1:地区 2:町 3:区域 4:犯罪大種別 5:成否 6:犯罪小種別 7:実行手段 8:年 9:月 10:日 11:時 12:性別 13:年代
06  awk '{print $7,$5}' \
07  | # 第七・第五フィールドの出力
08    ### 1:実行手段 2:成否
09  sort -k 1,1 \
10  | # 第一フィールドをキーとしてソート
11  uniq -c \
12  | # 各レコードの出現数を出力
13    ### 1:観測数 2:実行手段 3:成否
14  awk '{print $2,$1}' \
15  | # 第二・第一フィールドの出力
16    ### 1:実行手段 2:観測数
17  awk '{method[$1]=method[$1]" "$2} END{for(i in method){print i,method[i]}}' \
18  | # 第一フィールドをキーとして横集計
19    ### 1:実行手段 2:成功数 3:失敗数
20  awk '{print $1,$2/($2+$3)}'
21    # 各レコード毎の成功率を算出
22    ### 1:実行手段 2:成功率

最終問題だけあって、やや難易度高。
でも、逆にTukubaiコマンドの本領が発揮できる問題でもあった…​!!

以下、コピペ実行用のワンライナーコード。

Tukubai版。

cat hittakuri | self 7 5 | sort -k 1,1 | count 1 2 | delf 2 | yarr num=1 | awk '{print $1,$2/($2+$3)}'

Tukubai無し版。

cat hittakuri | awk '{print $7,$5}' | sort -k 1,1 | uniq -c | awk '{print $2,$1}' | awk '{method[$1]=method[$1]" "$2} END{for(i in method){print i,method[i]}}' | awk '{print $1,$2/($2+$3)}'

雑記

今回も遠隔での参加。
オープンデータを使うと聞いて、初めは難しいかと思っていたけれど、解き始めてみたら意外と簡単でした。
むしろ、今までこういった集計処理にシェル芸を使う機会が無かったので、とても良い訓練になったと思います!
集計処理となると、やっぱりawkが大活躍だぜ…​!!

また、今回ちょっと感じたこと。

シェル芸を使うと、元データさえあれば、非常に柔軟な集計作業ができる。
こういう風に、ふと疑問に感じたらその場ですぐに試せるというのは、シェル芸の大きな強みだと改めて感じました。

そして、前述したとおり、今回は各コマンドを実行した際のフィールド構成の変化を、強く意識して解答してみた。
今まではとにかくデータを加工する事だけを考えていたのだけれど、データ処理をフィールド単位で考えると、処理の流れがとても分かりやすくなったように思います。
また、分かりやすくなるだけでなく、集計処理に秀でているTukubaiコマンドを円滑に利用するためにも、非常に重要な作業だとも思いました。

ただ、解答が一般的なものばかりになってしまったのが、ちょっと残念。
というのも、『Software Design 2016年6月号』で、シェル芸には「 問題が解けてしまえば解が一般的でなくても良い 」という約束があることを、初めて知ったので…​
問題の性質上仕方が無いとはいえ、手っ取り早い解答も考えてみたかったです。

そんな中、この方の解答が、とても印象に残った。

今回の一般的な解ばかりが投稿される中で、このような予想もしなかった解答を思いついた事は、個人的にかなり凄いと思います!
僕もこういう柔軟な発想を身に着けたいぜ…​!!


LTでは、非常に面白くて変態的(特に大阪会場w)な発表も多くあったとのことで、是非とも見たかった…​!!
とはいえ、遠隔でも参加できるだけでも、本当にありがたいです。
(自宅参加組としては、ライブ配信が頼みの綱だったりするので…​)
勉強会を開催してくださった、上田会長をはじめとした日本UNIXユーザ会とUSP友の会の皆様、ありがとうございました!!

🐺。oO(次々回くらいまでには、名古屋サテライト会場開設の目処をつけたいなぁ…​ でも、その前に自分の就職先を探さねばorz)

Tags: シェル芸 Unix
このエントリーをはてなブックマークに追加