基本コマンド編:レコード集計2(xtcount)

xtaggコマンド以外に重要な集計コマンドとしてxtcountがある。これはキー項目の値が同じ行が何行あるかをカウントするコマンドである。


ここでは、先に作成したスクリプトxtcut.shを再利用することにする。xtcount.shという名前でコピーしておこう。

新しくコピーされたファイル"xtcount.sh"を編集する。xtcutで日付、数量、金額を抜き出しているが、ここでは、日付のみを抜き出すように変更する。
次に各日付の値が同じ行がぞれぞれ何行あるかを計算するためにxtcountコマンドを用いる。xtcountでは"-k"でどの項目を単位に(キー項目)集計するかを指定する。またxtcountは、計算した行数を新しい項目として付け加える。その時、新しい項目名を"-a"パラメータで指定しなければならない。
そして最後に、出力ファイル名(xtcount.xt)、およびコメントの変更も忘れずに。
これらの変更を反映させたスクリプトを下図に示しておく。

#!/bin/bash
xtcut -f 日付 -i /mnt/h00/tutorial/dat.xt |
xtcount -k 日付 -a 行数 |
xtheader -l "チュートリアル" -c "xtcount" -o xtcount.xt

ここで指定した三行の意味は次の通りである。
xtcutで「日付」の項目を選択し、その結果をパイプラインで次のxtcountコマンドに送る。xtcountコマンドでは、日付を単位に、行数が何行あるかを計算し、その結果を新しい項目名「行数」として追加する。そしてその結果データは再びパイプラインによって次のxtheaderコマンドに送られる。xtheaderコマンドは、タイトルとコメントを変更し、その結果を"xtcount.xt"というファイルに書き込む。

スクリプトの編集が終れば保存して、実行する。結果データを確認すると下図のように、日別にその行数が計算されている。
ここで新たに計算された「行数」という項目の意味は、各日に、レジで何回商品がスキャンされたかに等しい。

$ more xtcount.xt
<?xml version="1.0" encoding="euc-jp"?>
<?xml version="1.0" encoding="euc-jp"?>
<xmltbl version="1.1">
<header>
<title>チュートリアル</title>
<comment>xtcount</comment>
<field no="1" name="日付" sort="1"></field>
<field no="2" name="行数"></field>
</header>
<body><![CDATA[
20020101 105
20020102 32
20020103 116
20020104 78
20020105 43
20020106 76
20020107 67
20020108 69
20020109 113
20020110 82
20020111 116
20020112 132
20020113 85
--More--(8%)

さて、次に入力データ全ての行数が何行あるかをカウントしてみよう。その際にはキーとなる項目ないので(言い方をかえれば、全行が同じキー項目値をもつ)、-kパラメータを省略すればよい。
スクリプトは下図のようになる。

#!/bin/bash
xtcut -f 日付 -i /mnt/h00/tutorial/dat.xt |
xtcount -a 行数 |
xtheader -l "チュートリアル" -c "xtcount" -o xtcount.xt

実行結果は、下図のようになる。データは一行のみで、入力データの全行数が計算されている。これは、dat.xtに38733回の商品スキャンがあったということを意味する。

$ more xtcount.xt
<?xml version="1.0" encoding="euc-jp"?>
<xmltbl version="1.1">
<header>
<title>チュートリアル</title>
<comment>xtcount</comment>
<field no="1" name="日付"></field>
<field no="2" name="行数"></field>
</header>
<body><![CDATA[
20021231 38733
]]></body>
</xmltbl>
注)実は、第一項目の日付項目の値(20021231)は意味のないものである。行数を調べるために何らかの項目が入力データに必要となるが、ここではたまたま日付項目を利用したと考えればよい。他の金額や時間項目を日付項目のかわりに用いても全く問題ない。
OnePoint コマンドで指定しなかった項目はどうなるのか?
項目が「日付」のみの入力データに対して"xtcount -a 行数"を実行したとき、結果として、「日付」、「行数」の二項目が出力される。ここで、「日付」項目の値はどの日付になっているのであろうか?この質問は、前章で学習したxtaggについても同様に言える。「日付」、「数量」、「金額」を持つデータに対して"xtagg -k 日付 -f 数量 -c sum"と数量の集計だけを指定して実行した場合、「金額」項目の値はどの金額の値になっているのであろうか?
多くの場合においては、キー順で並べた場合の最後の値が出力される。上述のxtcountの例であると、「日付」項目で並べたときの最後の値、すなわち"20021231"が出力されている。しかし、例外もあるので、コマンドで指定しない項目についての値についてのルールは無いと考えておいたほうがよいであろう。

OnePoint -kの特殊な指定
-kで指定するキー項目名について特殊な指定がある。本章で学習した通り、-kパラメータが省略された場合、xtcountは全ての行が同じキー項目値を持つものとして動作する。しかし一方で、-kを省略すると全行異なるキー項目値をもつものとして動作するコマンドもある(例えば、xtcal)。
-kを指定できる全てのコマンドにおいて、キー項目値を全行同じとみなすか、全行異なるものと見なすかを明示的に指定することができる。全行同じに見なしたければ"-k #same#" と指定し、異なるものと見なしたければ"-k #diff#" と指定する。但し、多くのコマンドでは、このような明示的な指定は意味をなさない。例えば、"xtcount -k #diff#"と指定しても、計算される行数は全て"1"となる。
また注意点として、#same#、#diff#という項目名は、MUSASHIが上記の目的のために予約している項目名であり、ユーザは実際のデータの項目名としては利用することができない。

練習課題

次のようなデータを作成しよう。スクリプト名及び結果ファイル名は表に示されたものを使おう。

帳票名 スクリプト名 結果ファイル(xt) 結果ファイル(html)
メーカー別行数 xtcount1.sh xtcount1.xt xtcount1.html
ブランド別行数 xtcount2.sh xtcount2.xt xtcount2.html
大分類別行数 xtcount3.sh xtcount3.xt xtcount3.html
中分類別行数 xtcount4.sh xtcount4.xt xtcount4.html
小分類別行数 xtcount5.sh xtcount5.xt xtcount5.html
メーカー別中分類別行数 xtcount6.sh xtcount6.xt xtcount6.html