Dは,Dファイルのファイル演算を行う一連のコマンド群である。 Dコマンド名は大文字のDではじまる。
各Dコマンドは, Dファイルフォーマットのファイルに対し セレクションやジョイン(マッチング) などの基本的ファイル演算をおこなう。 結果も同じDファイルフォーマットで 標準出力に書き出される。 Dコマンドはシェルから呼び出され, 複数のDコマンドをつなげて,または他のコマンドとつなげて 複雑なデータ処理を行うことができる。
Dはオールインワンパッケージではない。 計算や文字列処理に関してはごく限られた機能しか持たない。 Dの基本理念はオープンシステムであり, sedやawkやperl など,あるいはほかの様々なプログラムと組み合わせて 用いることにより力を発揮する。
名称 | 説明 |
DfromLine | 行データからDファイルへ |
DfromChunk | 複数テキスト行からのDレコード作成 |
DtoLine | Dファイルから行データへ |
DfromCsv | CsvファイルからDファイルへ |
DtoCsv | DファイルからCsvファイルへ |
DfromHtml | HtmlからDレコードの抽出 |
DfromXml | XmlからDレコードの抽出 |
DtoXml | DファイルからXmlへ |
DtoTex | DファイルからTeXへ |
Dpr | Dファイルの表示/印刷 |
名称 | 説明 |
Dselect | 条件式を指定して検索 |
Dgrep | 正規表現での検索 |
Dextract | レコード番号リストによる抜出し |
Dhead | 先頭nレコードの抜出し |
Dtail | 最終nレコードの抜出し |
Dmax | 最大/最小値レコードの抽出 |
名称 | 説明 |
Dproj | プロジェクション |
Djoin | キーフィールド値によるDファイルのジョイン・マッチング |
Dpaste | Dファイルの水平マージ |
Drename | フィールド名の変更 |
Dorder | Dレコード中のフィールド順の変更 |
Dsort | キーフィールド値によるソート |
Dcat | Dファイルの連結 |
Dupdate | Dファイルの更新 |
Dfill | 空フィールドの補填 |
Ddecompose | Dレコードのフィールドインスタンス単位表現への変換 |
Dcompose | フィールドインスタンス単位表現からのDレコードの構成 |
名称 | 説明 |
Dbundle | キー値によるDレコードの垂直マージ |
Dunbundle | リピーティンググループによるDレコードのスライシング |
Dtie | グループフィールドの連結 |
Duntie | 1フィールドからグループフィールドへの分割 |
Dpack | リピーティグフィールドの連結 |
Dunpack | 1フィールドからリピーティグフィールドへの分割 |
Dファイルのデータモデルは以下のように極めて単純である。
<file> | ::= <record>の順序付集合 |
<record> | ::= <field>の順序付集合 |
<field> | ::= <field name>と<value>の対 |
DファイルはDファイル規約に従うテキストファイルである。 Dファイル規約を次に示す:
以上の規約によれば<value> には改行文字(NL)をのぞくどんな文字も含むことができる。 しかし,実装の便のため次の規約を付け加える。
この規則により <value> には, nl, nul および soh を含むことができず, また, <field name> には,上記の各文字に加えCOLON を含んではならないことになる。 これらの文字をのぞけばオペレーティングシステムの カレントなロケールでサポートされる限りのすべての文字が <field name>および<value> で使用可能である。
なお,上記規約の4.により,1ファイル中最後のDレコードは空行 をともなっていなくても良いことになる。 また,規約3.によりヌルレコード(fieldの数が0のレコード)は存在し得ない。 空行が連続した場合1つのレコード区切りとなるためである。
<field name> や <value> の長さには制限がない。 また, <record> 中の <field> の数にも制限がない。 ただし,システム上の限界は存在する。
Dファイル規約には, メールヘッダ(RFC # 822)で使われているような スペース文字を特別扱いする規則はない。 フィールド名区切りであるCOLONの後に空白があれば それも値のうちである。 また,1 <field> を複数行にわけて表現する手段もない。
<value> も <field name> も,空文字列(長さ0の文字列) であってよい。 しかしながら,空フィールド名(field nameが空文字列)を使用することは 推奨できない。いくつかのDコマンドは空フィールド名をフィールドスキップ のような特殊な機能のために使用している。
これに対し,空文字列を <value> に使用することは,何の問題もない。 ただし,空値(その <field name> を持った <field>が存在しない) と,フィールドが存在してその値が空文字列であることとは 厳密に区別する必要がある。 次の例で最初のレコードは,フィールド"b"が空値であるが, 2番目のレコードは,フィールド"b"が空文字列である。
例:
a:1
a:2
b:
ミッシングバリュー(欠値)を表すのにどちらの方法を使うかは 使用者の自由であるが, Dファイルとしてはこれらの値は異なるものとして扱われるので, 区別については意識しておく必要がある。
COLONを含まない行はエラーフィールドとなる。 エラーフィールドをどのように扱うかは, 各コマンドの実装にまかされる。 現在の実装では,一般に, エラーフィールドは出力レコードにもそのまま残される, という方針である。 ただし,フィールド名による選択をおこなう場合, エラーフィールドが選択されることはない。
カレントロケールでのエンコーディングに従わない バイト列は,エラーデータである。 Dコマンドはエンコーディングエラーに関して 警告メッセージを出力する。
NULL文字もエラーデータである。 現在の実装では,NULL文字は入力から無視され, 出力レコードには現れない。 メッセージも出力されない。
Dファイル中で数値は文字列として表される。 Dコマンドが数値のフィールドを作成する場合, 数値はprintf(3)の %d(整数)または%g(実数) で変換される。 Dコマンドが文字列を数値として評価する場合, その形式は, strtod(3)の受け付ける10進数表現または strtol(3)の受け付ける0xではじまる16進数表現 でなければならない。 (printf,strtod,strtol はC標準関数)。 これらの形式にあわない文字列は,0として評価される。 たとえば,
a:1/2
b:123c
c:1 2 3
はすべて,上記の形式にあわないため0として評価される。 Dコマンドは,これらの形式外ゼロ評価についてメッセージは出力しない。 また,小数点はロケール依存であり,常にFULL STOP (.)文字とは 限らないことにも注意せよ。
Dレコードには同じフィールド名のフィールドが2つ以上存在しうる。 たとえば:
a:1
b:2
a:3
b:4
Dコマンドは,原則としてこれらリピーティングフィールドを 1次元動的配列として取り扱う。 すなわち,perlでの配列のように, 0個以上の単純値を一つの名の下に取り扱うことになる。 上記例では,フィールド"a"は値{ 1 3 },フィールド"b"は値{ 2 4 }, そしてフィールド"c"は存在しないが,もしその名前で評価すれば 空値,すなわち値{ }をもつと見なす。
配列の要素は,単純値でなければならない。 したがって,2次元配列や行列はDコマンドで直接取り扱うことはできない。 また,リピーティングフィールドを数値として評価すると, すべての要素は数値として評価される。 Dの配列は,数値と文字列を混在させることはできない。
Dコマンドの引数では,フィールド名に添え字を指定することはない。 もし,同一フィールド名の値を相対的位置によって異なる取り扱いをする のであれば,最初から異なるフィールド名を与えておくべきである。 ただし,D言語Dlでは, 添え字演算をサポートしている。
異なるフィールド名のフィールド順は問わない。 この原則の下に,次の2レコードは同値である。
a:1
b:2
a:3
b:4
a:1
a:3
b:2
b:4
しかし,同じフィールド名のフィールド順は有意である。 次のレコードは,上記各レコードとと異なる。 フィールド"a"の値が{ 3 1 }であり,上記レコードの{ 1 3 } とは異なっているためである。
a:3
b:2
a:1
b:4
リピーティンググループを扱うコマンド (Dunbundle や Dtie) は,フィールド順をリーフの検出に使用する。 この場合に限り,異なるフィールド名のフィールド順も 意味を持つ。 (詳細はマニュアル D_lsaを見よ)。
明示しない限り,Dコマンドは入力ファイルのフィールド順を保持する。 たとえば,フィールド順を変更する Dorder コマンドでも,フィールドリストに指定されていない フィールドのフィールド順は保持する。
値は,文字列または数値のいずれかとして比較される。 省略時では文字列比較となる。 キーフラグ(キーフィールドリスト参照) で数値を指定しない限り,文字列比較となる。 (ただし,D言語ではこの他にも数値比較となる場合がある)。
文字列の大小比較は,各文字の内部処理コードの順にしたがう。 Windowsの場合,内部処理コードはUNICODE(ISO 10646 UCS2)となる。 Gnu/Linuxでは,内部コードはUNICODE (ISO 10646 UCS4)である。 その他のUNIXの場合,内部処理コードはロケールによっても異なることがある。 各オペレーティングシステムのマニュアルを参照すること。
数値比較をする場合,文字列は数値に変換された後変換される。 数値として正しくない形式の文字列は,0に変換されるので注意すること。 (数値参照)。
リピーティングフィールドの場合,最初の要素同士を比較し, それが等しい場合,次に2番目の要素同士を比較する というように等しくない要素が現れるまで, あるいは片方の要素がなくなるまで続く。 片方の要素が尽きだ場合,つきた側が小さいと定義する。 言葉を換えれば,存在しないフィールドは最小の 値(空文字列より小,マイナス無限より小)を持つと考えることにあたる。
2つ以上のフィールドを組み合わせて比較する場合も同様である。 フィールド"a,b"を比較する場合,まずフィールド"a"同士を比較し, それらが等しいときフィールド"b"同士を比較する。 フィールド"a"とフィールド"b"のレコード内でのフィールド順は 比較に影響しない。
リピ-ティンググループは,レコードの中で 繰り返す組になったフィールド群である。 例えば,次のDレコード
continent:Asia
code:CN
name:China
code:JP
name:Japan
code:KR name:Korea (the Republic of)
で,フィールドcodeとフィールドname は、対になって3回繰り返している。 Dファイル規約には,入れ子になったフィールドのような構造を明示的に示す方法 はない。 ただし,ある種のDコマンドでは, リーフセパレーションアルゴリズムを使って, この種の構造を扱うことができる。
一般的には,Dunbundle によって,構造をフラット化する, あるいは,Dtieによって リピーティンググループをリピーティングフィールドに変換するなどの方法をとる。 いくつかの使用例が D_tutorialにある。
Dコマンドの引数は次の規則にしたがう。
次のオプションは多くのDコマンドにおいて同じ意味で使用される。
-? | ヘルプ |
-F | ファイルごとの処理,"filename"フィールド付加 |
-g | グループ化 |
-k | 省略時キーオプション (キーフィールドリスト参照) |
-t | フォーマットの省略時区切り字列(D_fmt 参照) |
-z | フォーマットの省略時オプション(D_fmt 参照) |
-D | Dコマンド内部変数の定義(Dコマンド内部変数 参照) |
--help | ヘルプ。-?と同じ。 |
--version | バージョン出力 |
いくつかのDコマンドでは引数で正規表現を使用する。 正規表現はUNIXのegrep仕様にしたがう。
| | 左辺または右辺にマッチ |
* | 直前のものの0個以上にマッチ |
+ | 直前のものの1個以上にマッチ |
? | オプショナル; 直前のものの0個または1個にマッチ |
( ) | グルーピング; 正規表現のグループ化 |
. | 1文字; 任意の1文字にマッチ |
^ | 先頭; 文字列の先頭の空文字列にマッチ |
$ | 末尾; 文字列の末尾の空文字列にマッチ |
\ | エスケープ; 続く1文字にマッチ |
[...] | 範囲; 囲まれた中の任意の1文字にマッチ |
[^...] | 排他範囲; 囲まれた中の先頭の"^"を除く任意の1文字にマッチ |
- | []中,この左の文字から右の文字まで 内部処理コードとして連続した文字を並べたものの略記 |
[ ]の中で"\"はエスケープとして働かないことに注意すること。 また[ ]の中で"]","^"または"-"を 使用するには,それらの文字を意味のないところに配置する。 は先頭("["の直後または,"[^"の直後)におけばよい。 "^"は先頭以外の場所におけば普通の文字として扱われる。 "-"は先頭または最後におけば普通の文字扱いとなる。 なお,"-"の使用にあたっては内部コード についての知識が必要とされるので注意すること。
現在の実装における正規表現処理ルーチンは Henry SpencerのV8 regular expressionにもとづき 国際化に関する変更をおこなったものである。 この正規表現でのマッチは,常に「文字」にもとづき 「バイト」は扱わない。
多くのDコマンドにおいて フィールドリスト がオペランドやオプションの引数に使われる。 フィールドリストはCOMMAで区切られた フィールド名のならびである。
D-2.6より前のバージョンでは,空白もフィールド名の区切りであった。 このためにフィールドリスト中で空白を使用することが面倒であり, とくにフィールドフォーマットリスト中で問題が多かった。 このためD-2.6以降では,フィールド名の区切りは COMMAのみとする。
フィールドリストの文法をやや形式的に書くと次のようになる。
<field-list> | ::= | [^] [<fspec> [{,<fspec>}..]] |
<fspec> | ::= | <field name>[:<additional-inf>] |
COMMAの後ろにSPACEがあると,次のフィールド名の一部となるので注意。
"a, b"
上例で,最初のフィールド名は1文字の"a"であるが,次のフィールド名は, "b"でなく2文字の" b"となる。
フィールドリスト中でCOMMA(,)またはREVERSE SOLIDUS (\) を用いるには,REVERSE SOLIDUSを前につける。 先頭にCIRCUMFLEX ACCENT(^)を持つフィールド名を フィールドリストの先頭で指定するときもREVERSE SOLIDUS をその前につける。
"\^ab\,cd,\\ef"
"\ef,^ab\,cd"
最初の行は,"^ab,cd"というフィールドおよび "\ef"というフィールドになる。 フィールドリスト中のREVERSE SOLIDUSは, COMMAまたはREVERSE SOLIDUSの前にあるとき, (あるいは,フィールドリストの先頭にあって次の文字がCIRCUMFLEX ACCENTのとき) のみ取り除かれる。そのほかのREVERSE SOLIDUSは,そのまま残る。 したがって,2行目のリストは1行目と同じ"\ef"および "^ab,cd"というフィールドとなる。
フィールドリストには,各フィールド名ごとに付加情報をつけることができる。 付加情報は,フィールド名の後ろにCOLONで区切ってつなげる。 この付加情報の中でもREVERSE SOLIDUSエスケープは有効となる。 付加情報はキーフラグ,入出力フォーマット,新フィールド名などを指定する ために使われる。 この付加情報の種類によってフィールドリストは キーフィールドリスト, フィールドフォーマットリスト, リーフフィールドリスト, または フィールドリネームリスト となる。 これらの特定フィールドリストについては以下の節を参照のこと。
フィールドフォーマットリストの一般形は
field-name[:format]
というエントリのリストである。 フィールドフォーマットリストは, 文字列をDフィールドに,または Dフィールドから文字列に変換するための 方法を指定する。 フィールドフォーマットリストには 2つのオプション -t と -z によって省略時オプションが指定できる。
フォーマットの詳細についてはマニュアル D_fmt を参照。
キーフィールドリストの一般形は
field-name[:key-flags]
というエントリの並びである。 キーフィールドリストはキー値として使うフィールドを その属性(例えば文字列か数値かなど)とともに指定する。 キーフィールドリストについては -k オプションによって省略時キーフラグを与えることができる。
キーフラグは次の文字からなる文字列である。 (これらのフラグの意味はUNIXのsortと同じでそのサブセットになっている)。 これらによってフィールドのキー属性を指定する。
-k オプションのフラグはキーフラグリストのうち キーフラグをともなっていないフィールドに有効である。 したがって,次の各例は同じ意味になる。
"a,b:nr"
-k nr "a: b"
-k n "a: b:nr"
しかし,次の例は上記例とは異なる。
-k n "a: b:r"
フィールド"b"はこの場合数値フィールドとはならない。
キーフラグ"f"と"d"はロケールのライブラリが サポートしていればASCII以外の文字についても有効である。
キーフラグリスト中に同一フィールド名が重複していても かまわない。ただし,その場合の解釈は各コマンドによって 決められる。 多くの場合,最初のものだけが有効となる。
リーフフィールドリストの一般形は
fieldname[:*]
というエントリの並びである。 リーフフィールドリストは, Dunbundle および Dtie で,リーフとして扱われるフィールド群を その繰り返し可能性とともに指定する。 Dtie の場合,リーフフィールドリストは 同時にフィールドフォーマットリストも兼ねる。 実際リーフフィールドリストはフィールドフォーマットリストの サブセットであり,そのうちのフィールド名と"*" とだけが使用される。
詳細は,マニュアル D_lsa を参照。
フィールドリネームリストの一般形は
old-field-name:new-field-name
というエントリの並びである。 フィールドリネームリストは Drename で,フィールド名の変更を指定するのに使用される。 "\"によるエスケープはnew-field-name中にも適用される。 たとえば,フィールド名"a-b"を"a b"に変更するには 次のフィールドリネームリストを用いる。
"a-b:a\ b"
COLONがnew-field-nameに入っているかどうかのチェックは行わないので
"a:b:c"
というフィールドリネームリストを書くことはできるが, 結果は値の先頭に"c:"という文字列のついたフィールド"b" を作るだけである。 将来のバージョンではこのチェックを行う可能性もあり, このような使用法は推奨できない。
CIRCUMFLEX ACCENT(^)ではじまるフィールドリストは 排他を意味する。(この記法は正規表現の[^..]から来ている。) 排他フィールドリストはフィールドリストを使用できるところでは コマンドでの意味に矛盾のない限り使用できる。 一方の極端で,"^"は「すべてのフィールド」を意味するものとして 使用できる。
ただし,排他フィールドリストでは付加情報は意味を持たず, 書いても無視される。 しかし,排他フィールドリストを field-format-listや key-field-list に用いることに問題はない。 これらの特定フィールドリストに排他フィールドリストを用いた場合, 省略時のフォーマットやキーフラグが用いられる。
排他フィールドリストのDコマンド中の処理では 内部的に作業用フィールドリストが作られる。 このフィールドリストはプログラムの開始時点では 空になっている。処理を始めると排他フィールドリストに ないフィールド名を見つけるごとに,そのフィールド名を 作業用フィールドリストに登録する。 この作業用フィールドリストが処理用に使用されるため 実際のフィールドリストの順は入力ファイルに依存して決まる。
このことは Dorder や key-field-list のようにフィールド順に意味のある場合重要となる。 たとえば,次の用に指定した場合,
Dsort ^a file1 > tmp1
Dsort ^a file2 > tmp2
Djoin ^a tmp1 tmp2
3番目のDjoin コマンドでエラーとなることがある。 なぜなら,最初のDsortdでできる作業用フィールドリスト と次のDsortdでできる作業用フィールドリスト とが同じとは限らないためである。
Dコマンドの内部変数のあるものはユーザ指定可能で,コマンドの働きを制御できる。 コマンド引数-Dは,内部変数に値を与える。 その形式は次の通りである。
-D 変数名=値[,.. ]
変数名と指定できる値は各コマンドによって決められている。 各コマンドのマニュアルページ参照。 ただし, UTF入出力機能 用のDコマンド内部変数は共通である。 たとえば,
-D datautf=8
は,ほとんどのコマンドでUTF-8コードでの入出力を可能とする。
Dコマンドは結果の出力を標準出力ファイルに出す。 メッセージを出力する場合は標準エラーファイルに出す。 結果の出力も,原則としてDファイルである。 DtoLine, DtoTex, および Dpr は例外で,標準出力に Dファイルでないものを出力する。 Dsort は,標準出力,標準エラー以外に 一時ファイルとしてソートワークファイルを, Windosの Dpr はプリンタ出力時に一時ファイルを使用する。 これらだけが,標準出力,標準エラー以外のファイルに 出力する例外である。
Dコマンドのいくつかは,出力中に決まったフィールド名の フィールドを使用する。 たとえば, Dcat および他のいくつかのDコマンドは"filename"フィールドを出力する。
これら既定フィールド名は,たとえ入力ファイル中に同名のフィールドが あったとしても変更はされない。 この場合,"filename"フィールドがリピーティングフィールドとして出力中に 現れることになる。 Dコマンドの付加するフィールドが,既存のフィールドより前に来るか 後にくるかは,各Dコマンドの仕様により定まる。 Dcat の場合,"filename"フィールドは常にレコードの先頭のフィールドとして 付加される。
リピーティングフィールドになるのが都合悪い場合, Drename によってあらかじめ既存のフィールド名を変更しておくこと。 既定フィールド名を変更する手段は他にはない。
Dコマンドは,文字コード,数値表現,日付と時刻の表現の点で国際化されている。 メッセージは,国際化されておらず,常に英語である。
Dファイルは,基本的にロケール依存である。 異なるロケールで作成したDファイルを処理する場合, 作成ロケールと処理ロケールとの間で,文字コードと数値表現が 同じでなければ,Dコマンドがエラーを起こすこともある。
たとえば,"ja_JP.UTF-8"ロケールで作成されたDファイルを カレントロケール"ja_JP.eucJP"で読む場合, Dコマンドはコードエラーの警告メッセージを発したり, あるいは,正常終了しても誤った結果を出力することがある。
異なる数値表現も誤りの原因となりうる。 たとえば,Dmeansを フランス語ロケールで使用して,次のようなフィールドを得たとしよう:
avg.size:2,5
これを英語のロケールで読むと,この値は2.5ではなく,0として評価されてしまう。 (数値参照)。
Dコマンドの入出力データ,メッセージ,およびコマンド引数は,原則として ロケールの文字コードにしたがって処理される。 しかし,これには二つの例外がある。
ひとつは,DfromHtmlおよび DfromXmlである。 HTMLやXML入力ファイルには(通常)文字コード指示があり,これらのコマンドでは その文字コードが使われる。 この場合,出力データ,コマンド引数,およびメッセージは,入力データのコードに 関わらず,カレントロケールの文字コードが使われる。
もう一つの例外が次の節に述べるUTF入出力機能である。
入力文字コードがロケールの文字コードと異なると,出力ロケールのコードにない文字が現れることがある。 出力文字セットにない文字は,QUESTION MARK(?)に変換される。
Dコマンドは,ロケールの文字コードにかかわらずUTF-8/16/32コードのデータ入出力が可能である。 UTF入出力機能は,環境変数によって,またはコマンド引数から Dコマンド内部変数を 与えることによって指示される。 UTF入出力機能は,入出力データのみに適用され,コマンド引数およびメッセージは つねにロケールの文字コードとなる。 UTF入出力機能を指示する変数は,次の表に示す3種類ある。
環境変数 | Dコマンド内部変数 | 値 | 説明 |
Ddatautf | datautf | 8, 16, 32 | 入出力データコード |
Didatautf | idatautf | 8, 16, 32, -16, -32 | 入力データコード |
Dodatautf | odatautf | 8, 16, 32 | 出力データコード |
環境変数とDコマンド内部変数の双方が与えられた場合, Dコマンド内部変数が優先する。 datautf と i/odatautf の双方が指定された場合, i/odatautf の値が使用される。
これらの変数の値は次の表に示す意味を持つ。
[i/o]datautfの値 | 意味 |
8 | UTF-8エンコーディング |
16 | UTF-16エンコーディング |
32 | UTF-32エンコーディング |
-16 | 逆エンディアンのUTF-16 |
-32 | 逆エンディアンのUTF-32 |
たとえば,
Ded -D datautf=8 -f program.dl input.d
は, 入力ファイルinput.dと Dlプログラム入力ファイルprogram.dl とがUTF-8コードであることを指示する。
UTF入出力機能は,システムの内部コードがISO 10646 UCSの 場合に有効である。 したがって,Windowsおよび 最近の linux のディストリビューションでは使用可能であるが, SolarisでEUCコードのロケールを用いている場合には使用できない。 (UTF-8コードのロケールの場合,UTF入出力機能を使用できるが, この場合,環境変数やDコマンド内部変数を用いずともUTF-8は使用できる。)。
UTF入出力機能のねらいは,ひとつにはロケールとしてUTF-8をサポートしていない WIndows 上でUTF-8を処理することにあり, もうひとつは,UTF-16/32の内部コードを直接入出力することにより, コマンド間入出力のオーバーヘッドをへらすことにある。
Dコマンドの戻り値はすべて0から3の値で,その意味は次の通りである。
D_fmt, D_lsa, D_msg, D_tutorial。
MIYAZAWA Akira