入力データ(ファイルや標準出力)の指定されたフィールドをキーとして、指定されたフィールドの値を集計して出力します。
入力データのキーとなるのは最初に指定される2つのフィールドです。同じ値を指定することで単一のフィールドをキーとして指定することもできます。
集計される対象は3番目のオプションで指定されたフィールドから4番目のオプションで指定されたフィールドまでの連続したフィールドになります。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
$ cat << EOF | sm2 1 2 4 8 0001 新橋店 20060201 91 59 20 76 54 0001 新橋店 20060202 46 39 8 5 21 0002 池袋店 20060201 30 50 71 36 30 0002 池袋店 20060202 78 13 44 28 51 0003 新宿店 20060201 82 79 16 21 80 0003 新宿店 20060202 50 2 33 15 62 0004 上野店 20060201 60 89 33 18 6 0004 上野店 20060202 95 60 35 93 76 EOF 0001 新橋店 137 98 28 81 75 0002 池袋店 108 63 115 64 81 0003 新宿店 132 81 49 36 142 0004 上野店 155 149 68 111 82 |
この場合は第 1 フィールドと第 2 フィールドをキーにして、第 4 フィールドから第 8 フィールドまでの値を集計しています。
+count オプションはキーの数をキーの直後に出力します。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 |
#!/bin/sh awk -v "f1=$1" -v "f2=$2" -v "s1=$3" -v "s2=$4" '{ s = "" if(data[$f1" "$f2]){ # ハッシュにデータが存在する場合 # データをスペースで区切り配列 d に格納 split(data[$f1" "$f2], d, " ") # フィールド毎に加算して配列 d に格納 for(i=s1; i<=s2; i++){ d[i-s1+1] += $i s = s " " d[i-s1+1] } } else{ # ハッシュにデータが存在しない場合 for(i=s1; i<=s2; i++){ s = s " " $i } } # 行データをハッシュ data に格納 data[$f1" "$f2] = s } END{ # データ出力 for(i in data) print i, data[i] }' |
基本的な機能は全て awk(1) の組み込み関数で実装しました。
指定されたキー1とキー2は、出力する必要があるのでスペースを区切りとして連結しハッシュテーブル data のキーとします。
集計対象のフィールドは後に容易に計算できる様にスペース区切りの文字列とし、ハッシュテーブル data に格納します。
同じキーのデータが入力された場合は、ハッシュテーブル data からデータを取得してawk(1) の split 関数を利用してスペース区切りで配列 d に格納し加算処理を実施し、再度スペース区切りの文字列に戻してからハッシュテーブル data に格納します。
最後は配列 data の全要素を出力して処理終了です。
awk(1) の仕様としてハッシュの順番はランダムになりますが、sm2 コマンドでは出力行の順番を決定できる要素がないため、データの出力順序が保証できずランダムな順番のままの出力となります。
+count オプションは実装していません。
今回の記事のためにシェルスクリプトで Open usp Tukubai コマンドのうち幾つかを実装してみましたが、usp Tukubai コマンドは機能が豊富で、細かい部分に留意されていることが良く理解できました。特に帳票処理や集計処理、データベース関連の処理などには、必要にして十分な機能を備える専用のコマンドが数多く提供されているので、コマンドをパイプで繋ぐだけで業務システムの相当な機能が実現可能と言えるでしょう。数多くの業務システムに導入された実績から、本当に必要な機能が十分に検討されてきた結果だと思います。
また usp Tukubai のコマンドは高機能ですが、コマンド単体として見ると単純な機能に特化していて、一般的な unix コマンドの様に数多くのオプションで動作が変わってしまう様なことも殆どないために、それぞれのコマンドの習得に要する時間は非常に短時間ですみ、使い方を間違えたりコマンドのオプションを間違えることでバグを作り込んでしまうリスクが極限まで減らせると思います。
もう1点気づいたことは、データを集計した後に、画面に表示したり印刷する処理がとても簡単にできることです。
通常の unix コマンドの場合、単純なデータの集計は得意な分野だと言えますが、集計した結果を綺麗に画面に表示したり印刷したりするのは、意外と苦手な分野ではないでしょうか。
元々 unix にはそもそもの設計思想として、印刷や整形して出力するという文化があまり根付いておらず、綺麗に整形印字するコマンドは伝統的に数少なく、roff の様に存在したとしても判りづらい物でした。
usp Tukubai では、簡単な指定でそれらの出力の面倒をいい感じにみてくれるコマンドが複数提供されており、それらを活用すれば綺麗な出力を簡単に手に入れられるので、特に日本の業務システムには重要な機能なのだと思います。
そして整形機能と言えば、マルチバイト文字への対応が素晴らしいと感じました。
例えば、 OS X 標準の awk ではマルチバイト文字に対応していないので、usp Tukubaiでいうところの keta や self といった整形して表示する処理を自力で実装しようとすると、なかなか正しく動作しません。
GNU awk はマルチバイト文字列に対応していますが、表示幅に関しては一般的な表示幅としての処理しかされておらず、マルチバイト文字を綺麗に正しく整形するためにはシステム標準の機能だけでは無理でした。
usp Tukubai コマンドでは、マルチバイト文字の表示幅を 2 として扱っているので画面表示の時に便利で判りやすく、keta で切り出し位置や長さを指定する場合も直感的で判り安くなっていたのが素晴らしかったです。
今回シェルスクリプトで usp Tukubai コマンド相当のコマンドを実装してみて、usp Tukubai コマンドは機能が豊富で、細かい部分に留意されていることが良く判りました。
特に入力データに対するチェック処理は、必要十分かつ丁寧にチェックされていることからも、「(業務を知っている人が)業務処理をシステム化するためのDIYツール」という位置づけが明確になっていると思います。
業務を熟知した企業の中の人が単機能のコマンドを組み合わせてシステムを構築できれば、生産性が圧倒的に向上します。
しかも基本的なエラーチェックや細かい整形出力処理は usp Tukubai の処理がまとめて面倒をみてくれるので、システムの本質的な部分に注力できるというのは非常に素晴らしいです。
以上、とても駆け足になってしまいましたが usp Tukubai コマンドの特長と長所を紹介しました。
少しでも興味を持たれた方は、まずは是非とも Open usp Tukubai コマンドを触ってみて下さい。
シェル芸は元より普段の業務で利用している定型処理がとても楽になるでしょう。
(Personal Tukubaiのご注文もお待ちしています:シェルマガ編集部)
本記事掲載のシェルスクリプトマガジンvol.48は以下リンク先でご購入できます。
USP研究所 通販サイトでは、個人用uspTukubaiのご購入も可能です。