課題
ターミナル上で大量のデータを処理したい。 例えば、センサーからストリーム出力されるデータをその場でサクッと解析したい。 また、例えば、システムのログ出力から必要なものだけを抽出してシステムの状態を確認したい。
解決策
大抵の場合は以下のようなコマンドを組み合わせることで事足りる。
- wc
- sort
- uniq
- awk
この記事では以下のデータを題材としていろいろな処理を行ってみる。
これは個人的な映画鑑賞記録である。 この記事ではその文脈で、シェルスクリプトで何をしたいか記載する。
データはプレーンテキストで保存されているとする。 先頭は10行は以下のようになっている。 なお、この記事で処理をするデータは、この記事の初公開時点(2023/11/10)のものとする。
$ cat inputdata.txt | head 1 2022/12/23 AC四條畷 2 2022/12/25 AC大日 3 2022/12/26 AC四條畷 4 2022/12/28 梅田ブルク 5 2022/12/28 なんばパークスシネマ 6 2022/12/29 大阪ステーションシティシネマ 7 2022/12/29 ACシアタス心斎橋 8 2022/12/30 TOHOくずは 9 2022/12/31 梅田ブルク 10 2023/01/02 大阪ステーションシティシネマ
データを数える
鑑賞回数を知りたい。
$ cat inputdata.txt | wc -l 58
データをソートする
鑑賞日の新しい順にデータを確認したい。
$ cat inputdata.txt | sort -k2,2r | head 58 2023/11/05 みやま市立図書館 57 2023/09/17 シネマ・チュプキ・タバタ 56 2023/07/23 目黒シネマ 55 2023/06/15 なんばパークスシネマ 54 2023/06/14 大阪ステーションシティシネマ 53 2023/06/11 あべのアポロシネマ 52 2023/06/10 なんばパークスシネマ 51 2023/06/09 大阪ステーションシティシネマ 50 2023/06/08 TOHO門真 49 2023/06/04 なんばパークスシネマ
※紙面の関係上、先頭10行のみを表示するようにしている。
特定のデータを抽出する
なんばパークスシネマを訪れた日付を知りたい。
$ cat inputdata.txt | gawk '$3=="なんばパークスシネマ"{print}' | gawk '{print $2}' 2022/12/28 2023/01/12 2023/03/18 2023/03/19 2023/03/26 2023/03/27 2023/04/15 2023/04/24 2023/05/27 2023/06/04 2023/06/10 2023/06/15
特定のカラムについて集計する
シアター訪問数のランキングを知りたい。
$ cat inputdata.txt | gawk '{print $3}' | sort | uniq -c | sort -k1,1nr 12 なんばパークスシネマ 8 AC大日 6 大阪ステーションシティシネマ 4 TOHOくずは 3 AC四條畷 3 TOHO門真 2 梅田ブルク 2 ヱビスシネマ 2 あべのアポロシネマ 1 AC津南 1 ACシアタス心斎橋 1 MOVIX京都 1 MOVIXあまがさき 1 TOHO西宮 1 Tジョイ梅田 1 シネマネコ 1 チネチッタ 1 目黒シネマ 1 新宿ピカデリー 1 みやま市立図書館 1 下北沢トリウッド 1 丸の内ピカデリー 1 塚口サンサン劇場 1 シネマ・チュプキ・タバタ 1 グランドシネマサンシャイン
データを加工したうえで集計する
月ごとの鑑賞回数を知りたい。
$ cat inputdata.txt | gawk '{sub(/\/[0-9][0-9]$/,"",$2);print}' | gawk '{print $2}' | sort | uniq -c 9 2022/12 11 2023/01 9 2023/02 8 2023/03 6 2023/04 4 2023/05 8 2023/06 1 2023/07 1 2023/09 1 2023/11
所感
データ集計のために複雑なソフトウェアの複雑な機能に頼る必要はない。 大抵のことはシェルスクリプトで対応することができる。
シェルスクリプトに慣れないうちは、ひとつの操作を行うにも時間がかかってしまうかもしれない。 しかし、ひとたび慣れてしまえば、それぞれのコマンドがまるで手足として扱えるように思え、どんなことでも実現できるようになる。 その一端を本記事で表現できていればと願う。