シェルスクリプトマガジン

逆に、Tukubaiコマンドをシェルスクリプトで実装してみる 前編 (vol.47掲載)

著者:今泉光之 (Twitter: @bsdhack)

 

1 usp Tukubai とは?

usp Tukubai は ユニバーサル・シェル・プログラミング研究所が開発・提供している一連のコマンド群で、商用製品として様々な分野の数多くのプロダクトとして利用されているソフトウェア製品です。
usp Tukubai はコマンド群として提供されており、通常の UNIX コマンドの様に複数のコマンドを繋ぎ合わせて使うことでシステムを構築することができます。
usp Tukubai で提供されるコマンドを使いこなすと、端末だけで集計処理ができたり、ファイルだけでDBを組んだり、ウェブシステムを組んだりと、シェルあるいはシェルスクリプトでできることが飛躍的に増えます。
特に製品版として開発されている usp Tukubaiはソースコードのレベルからチューニングされているので、非常に高速に動作するので大規模なエンタープライズシステムでの使用にも十分に対応できる性能となっています。

2  ユニケージ開発手法とは?

ユニケージ開発手法はユニバーサル・シェル・プログラミング研究所によって開発された、短期間低コストで企業システムを構築するための開発手法です。
小さなコマンドを組み合わせて問題を解決することを目的とした開発手法やコマンドに関する研究開発に取り組んでいるユニバーサル・シェル・プログラミング研究所が、そうした研究開発の成果をまとめた開発手法がユニケージ開発手法です。
本稿で扱う usp Tukubai はユニケージ開発手法を実践するための手段として開発されたコマンド群です。
ユニケージ開発手法に基づいて usp Tukubai コマンドを利用することで、数十行のプログラムでアプリケーションを記述できたり、データベースを使わずにテキストファイルのみでデータ処理が可能となります。実際にユニケージ開発手法に基づくシステム開発は小売業を中心に基幹業務システム、情報分析システム、データバッチ処理、高速検索システム、勘定系システムなど様々な分野で活用されていて、特にシステムの内製化を進める企業において採用されています。

3 Personal Tukubai とは

usp Tukubaiを試用目的で利用できるようにしたバージョンで、商用利用はできません。
Windows、Linux、OS Xでそれぞれ動作するので usp Tukubai による業務システムの開発を実際に体験できます。
期間限定のライセンスで、ダウンロードした月から 6ヶ月後の月末まで使用可能となっているので、十分に usp Tukubai の機能を調べることができると思います。

4 Open usp Tukubai とは

usp Tukubai コマンドのうち、利用頻度の高いコマンドを厳選して Python により実装しなおし、MIT ライセンスの下でオープンソースソフトウェアとして提供されているのが Open usp Tukubaiです。
製品版の usp Tukubai と比較すると一部実装されていないコマンドがあったり、性能にある程度の差は出てしまいますが、それでも usp Tukubai の便利な機能を知るためには十分に有用だと思います。
本稿では、Open usp Tukubai についての解説となります。

Tukubai 各コマンドの機能の紹介と簡単な解説

1 Open usp Tukubai のインストール方法

Open usp Tukubai は Python により実装されているので Python が動作する環境であればインストール可能です。
公式の配布サイトからソースを取得して展開し make install するだけで Open usp Tukubai は利用可能となります。
OS X 11.6 (OS X El Capitan) では以下のコマンドでインストールできます。
$ curl ‘https://uec.usp-lab.com/TUKUBAI/DOWNLOAD/open-usp-tukubai-2014061402.tar.bz2’ -o open-usp-tukubai-2014061402.tar.bz2 $ tar zf open-usp-tukubai-2014061402.tar.bz2 $ cd open-usp-tukubai-2014061402 $ sudo make install

2 Open usp Tukubai コマンドの解説

ここでは Open usp Tukubai のコマンドを解説します。
ただし以下のように Open usp Tukubai だけでも 55 コマンドも提供されており、その全てを解説するのは無理なので、
特に有用で興味深いコマンドを厳選して紹介します。

また、シェルスクリプトマガジンに掲載の記事なので、シェルスクリプトで Open usp Tukubai コマンドを実装してみたいと思います。今回は、calclock、comma、getlast、ketaの4つのコマンドを紹介し、シェルスクリプトでの再現を試みます。
但し今回は紙面と時間の都合で一部の機能やオプションなど実装できていない部分も多いです。
また、動作の把握とメイン処理の実装のみに絞ったので、エラー処理などはまったく実施していません。
そのために実際の業務などには殆ど利用できない実験的なスクリプトとなっています。

calclock

1 calclock とは

オンラインコマンドマニュアルはこちら

入力データ(ファイルや標準入力)の指定されたフィールドのデータを Epoch *1からの秒数に変換してフィールドの隣に出力します。
ファイル名に – が指定された場合は一般的な UNIX の流儀にのっとり標準入力を入力として利用します。
入力データは年月日(yyyymmdd形式)、時間(HHMMSS形式)、年月日時間(yyyymmddHHMMSS)を自動で検出します。
例えば以下の様なフォーマットのシステムへの接続ログから接続時間を取得する処理などを簡単に作ることができます。

*1 Epoch とは UNIX で一般的に利用されている時刻表現で、協定世界時(UTC)での1970年1月1日午前0時0分0秒の時刻からの形式的な経過秒数です。

calclock 唯一のオプションは -r で、これを指定すると入力データは Epoch からの秒数として解釈され出力は年月日時間(yyyymmddHHMMSS)となります。

2 calclockを作ってみよう

シェル組み込みのコマンドと date(1) を駆使して、何とか似た機能は実現できました。
引数で指定されたフィールドを変数 fields に格納しておき、read(1) で入力した行データ毎に fields に格納されたフィールドから date(1) で秒数を取得し、取得できた秒を変数 v数字 (数字はフィールド番号) に格納しています。指定された全フィールドの処理が終わると、入力データと取得した秒数を出力します。入力データの指定されたフィールド形式などのチェックしていないので、入力データに不正な値があると正しく動作しません。また、今回は -r オプションに関して実装しておらず、入力データも標準入力のみとなっています。

comma

1 comma とは

オンラインコマンドマニュアルはこちら

入力データ(ファイルや標準入力)の指定されたフィールドのデータを「カンマ区切り」にします。帳票データなどの最終的な出力に適用すると、金額などの可読性が向上します。
指定したフィールドに数字以外のデータが入力された場合はエラーとなります。

+hオプションはヘッダ行をスキップするための指定で、指定された行(デフォルトは1行)をヘッダ行としてスキップします。

d オプションは引数で指定した文字列をカンマ区切りにします。

-4 オプションは 4 桁区切りにします。

2 commaを作ってみよう

メインのロジックは awk(1) を利用することで何とか実装できました。
awk(1) の substr 関数を利用して文字列の後ろから指定された桁数で文字列を切り出し、切り出した文字列の先頭に , を付けることでカンマ区切りを実現しています。
今回は -d オプションに関して実装しておらず、入力データも標準入力のみとなっています。また Open usp Tukubai の comma では桁区切りするフィールドのデータをチェックしていて、データが数字以外の場合はエラーメッセージを出力していますが、こちらのスクリプトではその様なエラー処理をしていません。
ちなみに 3 桁区切りだけでよければ printf(1) の %’ を利用することでも殆どの場合実現可能ですが、printf(1) の %’ は現時点では非標準なので全ての環境で利用できる保証はなく、また、区切りを 4桁にする機能は対応していないので、独自に実装する必要があります。

getlast

1  getlastとは

オンラインコマンドマニュアルはこちら

入力データ(ファイルや標準出力)の指定されたフィールドの値が最後に出現した行を出力します。

同一のフィールドを指定することで単一のキーフィールドの指定も可能です。
以下の例だと第1フィールドの値のみで抽出しています。

+ng オプションは同じ値を持つ最後の行以外を出力します。

2 getlastを作ってみよう

メインのロジックは awk(1) のハッシュ (連想配列) を利用することで実装しました。
指定されたフィールドの値をそのまま連結してハッシュのキーとして利用することで、最新の行内容がハッシュに格納されます。
awk(1) の仕様としてハッシュの順番はランダムになりますので、
順番を維持するためにハッシュに格納する行データに行番号を付与して、出力したデータを sort(1) を利用して行番号でソートして正しい順番に並べ替えた後で、cut(1) で追加した行番号を削除して出力しています。
メインのロジックは awk(1) の機能をそのまま利用することで実現できたので、今回実装したコマンドの中では一番短く単純なスクリプトになっています。
+ng オプションは実装していません。

keta

1 keta とは

オンラインコマンドマニュアルはこちら

入力データ(ファイルや標準出力)の指定されたフィールドの桁数を揃えて、右詰で出力します。
表示するための最大幅は自動で計算されます。

— オプションは左詰で出力されます。

フィールド毎に出力する桁数を数字で指定することができ、指定する数字に – を付けることで左詰を指定することもできます。
出力する桁数は半角文字の表示幅を 1 としているので全角文字の場合は 1 文字を 2 とする必要があります。

2  ketaを作ってみよう

基本的な機能は全て awk(1) の組み込み関数で実装しました。
入力データは行番号とフィールド番号をキーとしたハッシュ dataに格納し、同時にフィールドの文字列長の最大値を別のハッシュ max に格納しています。
出力は、 awk(1) に組み込みの printf の %*s 指示子を利用することで出力幅を指定しています。

マルチバイトの文字列には対応していないので、入力データにマルチバイト文字があると正しく出力できません。
非英語圏でマルチバイト文字が正しく扱えないことは致命的ですので、業務には利用できません。

UTF-8 では、マルチバイト文字は多くの場合 3 バイトかそれ以上のバイト数を必要としていますが、OS X 標準の awk(1) の lengthコマンドは文字列のバイト数を取得しますので、例えば length(“あ”) は 3 となります。
Linux で標準的に利用されている GNU awk の場合はマルチバイト文字に対応していますので、マルチバイト文字を含む文字列の長さは正しい文字数を取得することができ、length(“あ”) は 1 となります。
しかしマルチバイト文字は 2 バイト相当の表示幅となりますので、どちらの場合でもマルチバイト文字を含む文字列の長さと表示幅は合致しません。
そのためにマルチバイト文字を含む文字列を表示する幅を正しく制御するのは非常に困難となります。

-v オプションは実装していません。

5/25発売のシェルマガvol.48では、さらなるTukubaiコマンドに挑みます
Web版シェルマガにも公開しますので、どうぞお楽しみに!

本記事掲載のシェルスクリプトマガジンvol.47は以下リンク先でご購入できます。
USP研究所 通販サイトでは、個人用uspTukubaiのご購入も可能です。