Previous: インストール Up: Mコマンド Next: データ型 MCMD2
MCMD2 : Mコマンド : CSV

2.4 CSV

MCMDが処理する表構造データはFigure 2.5に例示されるようなCSV(Comma Separated Values)フォーマットである。 CSVは表構造データのフォーマットのデファクトスタンダードであり、アプリケーションプログラム間でのデータ交換用フォーマットとして 広く利用されている。

商品コード,商品名,分類,価格
0899781,パン,食品,128
8879674,オレンジジュース,飲料,98
3244565,チーズ,食品,350
6711298,茶碗,食器,168
Figure 2.5: CSVデータの例

しかしながら、CSVは標準化協会や企業主導で作成された標準フォーマットではなく、 それ故にベンダー毎にCSV の扱い方法が異なっているのが現状である。 その中で2005年10月にインターネット標準であるRFC4180としてCSVフォーマットが 提案されたのは注目すべき動きである。 Figure 2.6、RFC4180の中でABNF表現によるCSVの定義を示す。

(A) file = [header CRLF] record *(CRLF record) [CRLF]
(B) header = name *(COMMA name)
(C) record = field *(COMMA field)
(D) name = field
(E) field = (escaped / non-escaped)
(F) escaped = DQUOTE *(TEXTDATA / COMMA / CR / LF / 2DQUOTE) DQUOTE
(G) non-escaped = *TEXTDATA
(H) COMMA = %x2C
(I) CR = %x0D ;as per section 6.1 of RFC 2234 [2]
(J) DQUOTE = %x22 ;as per section 6.1 of RFC 2234 [2]
(K) LF = %x0A ;as per section 6.1 of RFC 2234 [2]
(L) CRLF = CR LF ;as per section 6.1 of RFC 2234 [2]
(M) TEXTDATA = %x20-21 / %x23-2B / %x2D-7E
日本語翻訳:
Figure 2.6: CSV のABNF による定義

Figure 2.6中の各行の意味は以下のとおりである。

  • (A) ファイル(file)は,ヘッダ(header)と1行以上のレコード(record)から構成される。ヘッダはなくてもよい。ヘッダとレコードの末尾には改行(CRLF)が付く。最終レコードの改行(CRLF)は任意である。

  • (B) ヘッダ(header)は1つ以上の名前(name)で構成され,カンマ(COMMA)で区切られる。

  • (C) レコード(record)は一つ以上の項目(field)で構成されており,

  • (D) 名前(name)は項目(field)である。

  • (E) 項目(field)はエスケープ(escaped)か,非エスケープ(non-escaped)のいずれかである。

  • (F) エスケープ(escaped)は,ダブルクォーツで囲まれた0個以上のテキスト文字(TEXTDATA),カンマ(COMMA),改行文字(CRもしくはLF),もしくは2つの連続したダブルクォーツである。

  • (G) 非エスケープ(non-escaped)は0個以上のテキスト文字(TEXTDATA)である。

  • (H) コンマは16進数アスキーコード2Cである。

  • (I) キャリッジリターン(CR)は16進数アスキーコード0Dである。

  • (J) ダブルクォーツ(DQUOTE)は16進数アスキーコード22である。

  • (K) ラインフィード(LF)は16進数アスキーコード0Aである。

  • (L) 改行ラインフィードはキャリッジリターン+ラインフィードである。

  • (M) テキスト文字(TEXTDATA)は16進数アスキーコードで20〜21,23〜2B,もしくは2D〜7Eである。

2.4.1 Mコマンド独自の定義

Mコマンドでは上記のCSVの定義に対して以下の制約を追加している。

  • 項目数は全行同じでなければならない。

  • 1行の最大長に制限を設ける(デフォルトでは1024000バイト(1MB),10MBまで拡張可能)。

  • 改行はLFのみとする。

  • 最終レコードであっても改行は必須とする。

  • テキスト文字として80〜FFを付け加える(マルチバイト文字を扱うため)。

利用するCSVファイルが上記の定義を満たしているか確かめるには mchkcsvコマンドを利用すればよい。

2.4.2 コマンドに共通した入出力の手順

多くのMCMDで行われるCSVファイルの入出力の手順は概ね以下に示す手順に従っている。

  1. ファイルからブロック単位でメモリに読み込む。

  2. エスケープ文字を考慮しながらカンマ区切りの項目単位の文字列に分解する。

  3. エスケープ文字を解釈しオリジナルデータに変換する(DQUOTEを外す)。

  4. コマンドの特有の処理を実行し,出力バッファに書き込む。

  5. エスケープが必要であれば,エスケープを付加する。

  6. バッファが一杯になればファイルに出力する。

2.4.3 項目の並べ替え情報

msortfコマンドを使用して項目の並べ替えを行った場合や、 他のコマンドでs=パラメータ・k=パラメータを使用した場合など、 データがある項目で並べ替えられていることが保証されるとき、 出力されるCSVファイルの項目名には、並べ替えに関する情報が付加される。 具体的には、並べ替え項目として指定した順に%0、%1、…と0から始まる番号が付加される。 数値として並べ替えたときにはnが、降順で並べ替えたときにはrがそれぞれ追加される。

$ msortf i=dat1.csv f=id%n,item o=rsl1.csv
#END# kgsortf f=id%n,item i=dat1.csv o=rsl1.csv
$ more rsl1.csv
id%0n,item%1,price
1,a1,100
2,b1,120
2,b2,200
$ msortf i=dat1.csv f=price%nr o=rsl2.csv
#END# kgsortf f=price%nr i=dat1.csv o=rsl2.csv
$ more rsl2.csv
id,item,price%0nr
2,b2,200
2,b1,120
1,a1,100

msumやmjoinなど多くのコマンドは集計・結合に必要な項目を 自身で並べ替えようとするが、入力ファイルの項目名からあらかじめ 並べ替えられていると判断すれば、その並べ替え処理を省略する。

項目名に並べ替え情報が付加されている場合でも、 f=パラメータ等で指定する場合には省略できる。

$ mcut i=rsl1.csv f=id,item
id%0n,item%1
1,a1
2,b1
2,b2

なお、項目名の並べ替え情報と実際のデータの並び順が整合していない場合 (実際には並べ替えられていないのに、項目名に%0が付加されているなど)、 各コマンドの動作は不定となる。

2.4.4 注意点

以下にCSVデータで注意すべき点について、例を交えながら説明する。

カンマを含むデータ

カンマを含むデータはダブルクォーツで囲われる。 以下は、f1,f2の2項目から構成されるCSVファイルで、0行目1 のf1項目はカンマを含んでいるのでダブルクォーツで囲われている。

f1,f2
"abc,def",2
xyz,2

ダブルクォーツを含むデータ

ダブルクォーツを含むデータはダブルクォーツで囲われ,かつ連続するダブルクォーツとして表現される。 以下は、f1,f2の2項目から構成されるCSVファイルで、 0行目と1行目のf1項目はダブルクォーツを含んでおり、 オリジナルのデータはそれぞれ「abc"def」,「"」である。

f1,f2
"abc""def",2
"""",2

改行を含むデータ

改行を含むデータもダブルクオーツで囲うことで処理可能である。 以下の例の0行目のf1項目は、abcの後に改行が含まれているが、ダブルクオーツで囲われているため、 行末ではなくデータの一部として識別される。

f1,f2
"abc
def",1

必要のないダブルクオーツ

以下のように必要ないデータに対してダブルクオーツを用いていた場合、コマンドの出力時には外される。

$ more data.csv
f1,f2
"abc",efg
abc,"efg"
$ mcut f=f1,f2 i=data.csv
f1,f2
abc,efg
abc,efg

Footnotes

  1. MCMDでは統一的に先頭行(項目名行を除いた最初の行)を0行目と呼称する。
Previous: インストール Up: Mコマンド Next: データ型 MCMD2