Unixコマンドで作るリレーショナルデータベース


latexデータだといろいろ使いまわしがきついので、atwikiにキーボードマクロで変換してみました。
ライセンスの扱いが良く分からなかったので、もし問題ならhogeika2@gmail.comまで連絡お願いします。

title Unixコマンドで作るリレーショナルデータベース
author 安岡孝一
place 漢籍担当職員講習会
type 「Unixと情報検索」資料
date 1994年10月6日(木)

はじめに

Unixにはリレーショナルデータベースを構築するためのコマンドがほぼそろっており、リレーショナルデータベースにおける1操作が1ラインで済むようになっています。
すなわちUnixでは、めんどくさいプログラムを組むことなく、個人用のデータベースを簡単に作ったり使ったりできるのです。

この冊子では、それらのコマンドを使用例とともにまとめてみました。
皆さんがデータベースを作る際の手助けとなれば幸いです。

Unixの基礎

この章では、この冊子を読むにあたって、最低限必要なUnixに関することがらについて述べます。
Unixについて一通りの知識のある方は、読みとばして下さってかまいません。
なお以下では、キーボードから打ち込んだ文字列にはアンダーラインを引いて表します。

ファイルの一覧表を出力する

ファイルの一覧表を出力するコマンドは「ls」です。
% ls
personnel       title1          title2
% 

ファイルの内容を出力する

ファイルの内容を出力するコマンドは「cat ファイル名」です。
% cat title1
Cool_Struttin'  Blue_Note_1588
Django Prestige_7057
Flight_to_Denmark SteepleChase_1011
Hi-Fly New_Jazz_8273
Waltz_for_Debby Riverside_9399
% 

出力をファイルに取り込む

コマンドの出力をファイルに取り込むには、
コマンドの後に「>ファイル名」とします。
これにより、いかなるコマンドの出力もファイルに取り込めます。
% ls > tmp
% cat tmp
personnel       title1          title2          tmp
% 

データベースファイル

フォーマット

この冊子で用いる表形式のリレーショナルデータベースファイルは、以下のようなフォーマットとなっているものです。

  1. 1行=1レコード
  2. 各レコードが同一数のフィールドを持ち、フィールドの区切りは空白1つである
  3. フィールド内の空白はアンダーラインに置き換える

例えば
Cool Struttin' Blue Note 1588
Django Prestige 7057
Flight to Denmark SteepleChase 1011
Hi-Fly New Jazz 8273
Waltz for Debby Riverside 9399
という表は、
次のような内容を持つデータベースファイルで表されます。
Cool_Struttin'  Blue_Note_1588
Django Prestige_7057
Flight_to_Denmark SteepleChase_1011
Hi-Fly New_Jazz_8273
Waltz_for_Debby Riverside_9399

正規化(normalization)

上記のフォーマットに従ったファイルでも、
同一のレコードがあったりすると正常な処理が行なえません。
そこで処理にさきだってファイルを正規化する必要があります。

ファイルを正規化するコマンドは「sort -u ファイル名」です。
例えば
Waltz for Debby Riverside 9399
Django Prestige 7057
Cool Struttin' Blue Note 1588
Flight to Denmark SteepleChase 1011
Hi-Fly New Jazz 8273
Cool Struttin' Blue Note 1588
という表、すなわち
% cat illegal
Waltz_for_Debby Riverside_9399
Django Prestige_7057
Cool_Struttin'  Blue_Note_1588
Flight_to_Denmark SteepleChase_1011
Hi-Fly New_Jazz_8273
Cool_Struttin'  Blue_Note_1588
%
というファイルillegalを正規化すると
% sort -u illegal
Cool_Struttin'  Blue_Note_1588
Django Prestige_7057
Flight_to_Denmark SteepleChase_1011
Hi-Fly New_Jazz_8273
Waltz_for_Debby Riverside_9399
% 
すなわち
Cool Struttin' Blue Note 1588
Django Prestige 7057
Flight to Denmark SteepleChase 1011
Hi-Fly New Jazz 8273
Waltz for Debby Riverside 9399
という表になります。

データに対する操作

この章では、リレーショナルデータベースにおける基本的操作それぞれについて、対応するUnixコマンドを紹介します。

結び(union)

2つのファイルの結びをとるコマンドは「sort -u ファイル名 ファイル名」です。
例えば
Cool Struttin' Blue Note 1588
Django Prestige 7057
Flight to Denmark SteepleChase 1011
Hi-Fly New Jazz 8273
Waltz for Debby Riverside 9399
という表(ファイルtitle1)と
Django Prestige 7057
Groovy Prestige 7113
Portrait in Jazz Riverside 1162
Speak Low Jazztime 002
The Bud Powell Trio Roost 401
Waltz for Debby Riverside 9399
We Three New Jazz 8210
という表(ファイルtitle2)との結びをとるには
% sort -u title1 title2
Cool_Struttin'  Blue_Note_1588
Django Prestige_7057
Flight_to_Denmark SteepleChase_1011
Groovy Prestige_7113
Hi-Fly New_Jazz_8273
Portrait_in_Jazz Riverside_1162
Speak_Low Jazztime_002
The_Bud_Powell_Trio Roost_401
Waltz_for_Debby Riverside_9399
We_Three New_Jazz_8210
%
とします。
これによって2つの表の結びである
Cool Struttin' Blue Note 1588
Django Prestige 7057
Flight to Denmark SteepleChase 1011
Groovy Prestige 7113
Hi-Fly New Jazz 8273
Portrait in Jazz Riverside 1162
Speak Low Jazztime 002
The Bud Powell Trio Roost 401
Waltz for Debby Riverside 9399
We Three New Jazz 8210
を得られます。

差(difference)

2つのファイルの差をとるコマンドは「comm -23 ファイル名 ファイル名」です。
これにより、
前のファイルにあって後のファイルにないレコードを選び出せます。
例えば

Cool Struttin' Blue Note 1588
Django Prestige 7057
Flight to Denmark SteepleChase 1011
Hi-Fly New Jazz 8273
Waltz for Debby Riverside 9399
という表(ファイルtitle1)と
Django Prestige 7057
Groovy Prestige 7113
Portrait in Jazz Riverside 1162
Speak Low Jazztime 002
The Bud Powell Trio Roost 401
Waltz for Debby Riverside 9399
We Three New Jazz 8210
という表(ファイルtitle2)の差をとるには
% comm -23 title1 title2
Cool_Struttin'  Blue_Note_1588
Flight_to_Denmark SteepleChase_1011
Hi-Fly New_Jazz_8273
% 
とします。
これによって2つの表の差である
Cool Struttin' Blue Note 1588
Flight to Denmark SteepleChase 1011
Hi-Fly New Jazz 8273
を得られます。

重なり(intersection)

2つのファイルの重なりをとるコマンドは「comm -12 ファイル名 ファイル名」です。
例えば
Cool Struttin' Blue Note 1588
Django Prestige 7057
Flight to Denmark SteepleChase 1011
Hi-Fly New Jazz 8273
Waltz for Debby Riverside 9399
という表(ファイルtitle1)と
Django Prestige 7057
Groovy Prestige 7113
Portrait in Jazz Riverside 1162
Speak Low Jazztime 002
The Bud Powell Trio Roost 401
Waltz for Debby Riverside 9399
We Three New Jazz 8210
という表(ファイルtitle2)との重なりをとるには
% comm -12 title1 title2
Django Prestige_7057
Waltz_for_Debby Riverside_9399
% 
とします。
これによって2つの表の重なりである
Django Prestige 7057
Waltz for Debby Riverside 9399
を得られます。

選択(selection)

ファイルから特定のレコードを取り出すコマンドは「awk' 条件 ' ファイル名」です。
条件には以下のものが使用できます。
i) $フィールド番号 =="文字列" 指定されたフィールドが文字列と等しい
ii) $フィールド番号 !="文字列" 指定されたフィールドが文字列と等しくない
iii) $フィールド番号 ~/文字列/ 指定されたフィールドが文字列を含む
iv) $フィールド番号 !~ /文字列/ 指定されたフィールドが文字列を含まない
v) $フィールド番号 == $フィールド番号 指定されたフィールド同士が等しい
vi) $フィールド番号 != $フィールド番号 指定されたフィールド同士が等しくない
vii) 条件 && 条件 2つの条件の論理積
viii) 条件||条件 2つの条件の論理和
(編集注: 当wikiでの|のエスケープ方法が分からなかったので全角にした)

例えば
Prestige 7027 Art Blakey drums
Prestige 7027 Percy Heath bass
Prestige 7027 Thelonious Monk piano
Prestige 7057 John Lewis piano
Prestige 7057 Kenny Clarke drums
Prestige 7057 Milt Jackson vibes
Prestige 7057 Percy Heath bass
Prestige 7113 Arthur Taylor drums
Prestige 7113 Paul Chambers bass
Prestige 7113 Red Garland piano
という表、すなわち
% cat personnel
Prestige_7027 Art_Blakey drums
Prestige_7027 Percy_Heath bass
Prestige_7027 Thelonious_Monk piano
Prestige_7057 John_Lewis piano
Prestige_7057 Kenny_Clarke drums
Prestige_7057 Milt_Jackson vibes
Prestige_7057 Percy_Heath bass
Prestige_7113 Arthur_Taylor drums
Prestige_7113 Paul_Chambers bass
Prestige_7113 Red_Garland piano
%
というファイルpersonnelから、
第3フィールドがpianoであるものを取り出すには
% awk '\$3=="piano"' personnel
Prestige_7027 Thelonious_Monk piano
Prestige_7057 John_Lewis piano
Prestige_7113 Red_Garland piano
% 
とします。
これによって
Prestige 7027 Thelonious Monk piano
Prestige 7057 John Lewis piano
Prestige 7113 Red Garland piano
という表が得られます。

射影(projection)

ファイルから特定のフィールドを取り出すコマンドは
join -o フィールド指定 -a1 ファイル名 /dev/null | sort -u
です。
フィールド指定は「1. フィールド番号」で行ない、複数のフィールドを指定することが可能です。
例えば
Prestige 7027 Art Blakey drums
Prestige 7027 Percy Heath bass
Prestige 7027 Thelonious Monk piano
Prestige 7057 John Lewis piano
Prestige 7057 Kenny Clarke drums
Prestige 7057 Milt Jackson vibes
Prestige 7057 Percy Heath bass
Prestige 7113 Arthur Taylor drums
Prestige 7113 Paul Chambers bass
Prestige 7113 Red Garland piano
という表(ファイルpersonnel)から、第3フィールドと第2フィールドをその順番で取り出すには
% join -o 1.3 1.2 -a1 personnel /dev/null | sort -u
bass Paul_Chambers
bass Percy_Heath
drums Art_Blakey
drums Arthur_Taylor
drums Kenny_Clarke
piano John_Lewis
piano Red_Garland
piano Thelonious_Monk
vibes Milt_Jackson
%
とします。
これによって
bass Paul Chambers
bass Percy Heath
drums Art Blakey
drums Arthur Taylor
drums Kenny Clarke
piano John Lewis
piano Red Garland
piano Thelonious Monk
vibes Milt Jackson
という表が得られます。

結合(natural join)

2つのファイルの第1フィールド同士による結合を行なうコマンドは「join ファイル名 ファイル名」です。
例えば
Jazztime 002 Speak Low
New Jazz 8210 We Three
Prestige 7057 Django
Prestige 7113 Groovy
Riverside 1162 Portrait in Jazz
Riverside 9399 Waltz for Debby
Roost 401 The Bud Powell Trio
という表、すなわち
% cat revtitle2
Jazztime_002 Speak_Low
New_Jazz_8210 We_Three
Prestige_7057 Django
Prestige_7113 Groovy
Riverside_1162 Portrait_in_Jazz
Riverside_9399 Waltz_for_Debby
Roost_401 The_Bud_Powell_Trio
% 
というファイルrevtitle2
Prestige 7027 Art Blakey drums
Prestige 7027 Percy Heath bass
Prestige 7027 Thelonious Monk piano
Prestige 7057 John Lewis piano
Prestige 7057 Kenny Clarke drums
Prestige 7057 Milt Jackson vibes
Prestige 7057 Percy Heath bass
Prestige 7113 Arthur Taylor drums
Prestige 7113 Paul Chambers bass
Prestige 7113 Red Garland piano
という表(ファイルpersonnel)の結合をとるには
% join revtitle2 personnel
Prestige_7057 Django John_Lewis piano
Prestige_7057 Django Kenny_Clarke drums
Prestige_7057 Django Milt_Jackson vibes
Prestige_7057 Django Percy_Heath bass
Prestige_7113 Groovy Arthur_Taylor drums
Prestige_7113 Groovy Paul_Chambers bass
Prestige_7113 Groovy Red_Garland piano
%
とします。
これによって
Prestige 7057 Django John Lewis piano
Prestige 7057 Django Kenny Clarke drums
Prestige 7057 Django Milt Jackson vibes
Prestige 7057 Django Percy Heath bass
Prestige 7113 Groovy Arthur Taylor drums
Prestige 7113 Groovy Paul Chambers bass
Prestige 7113 Groovy Red Garland piano
という表が得られます。

拡張(expansion)

ファイルの各レコードに同一内容のフィールドを追加するコマンドは「sed 's/\$/ 文字列 /' ファイル名」です。
例えば
Cool Struttin' Blue Note 1588
Django Prestige 7057
Flight to Denmark SteepleChase 1011
Hi-Fly New Jazz 8273
Waltz for Debby Riverside 9399
という表(ファイルtitle1)の各レコードに、jazzという内容のフィールドを追加するには
% sed 's/\$/ jazz/' title1
Cool_Struttin'  Blue_Note_1588 jazz
Django Prestige_7057 jazz
Flight_to_Denmark SteepleChase_1011 jazz
Hi-Fly New_Jazz_8273 jazz
Waltz_for_Debby Riverside_9399 jazz
% 
とします。これによって
Cool Struttin' Blue Note 1588 jazz
Django Prestige 7057 jazz
Flight to Denmark SteepleChase 1011 jazz
Hi-Fly New Jazz 8273 jazz
Waltz for Debby Riverside 9399 jazz
という表が得られます。

固定長レコードフォーマット

この冊子で用いてきたデータベースフォーマットに従ったファイルは、Unix上で扱うには非常に便利なものですが、人間が読むにはあまり適当とはいえません。
そこで一般に読みやすいと思われる、固定長レコードフォーマットとの変換を考えてみましょう。

固定長レコードへの変換

データベースフォーマットのファイルを、固定長レコードフォーマットに変換するコマンドは
tr ' ' '\011' < ファイル名| expand - 第1フィールド終了桁, 第2フィールド終了桁,…」
です。
例えば
% cat jazztitle1
Cool_Struttin'  Blue_Note_1588 jazz
Django Prestige_7057 jazz
Flight_to_Denmark SteepleChase_1011 jazz
Hi-Fly New_Jazz_8273 jazz
Waltz_for_Debby Riverside_9399 jazz
%
というファイルjazztitle1を、第1フィールド25文字、第2フィールド20文字の固定長レコードフォーマットに変換するには
% tr ' '  '\011 '  < jazztitle1 | expand -25,45
Cool Struttin'           Blue Note 1588      jazz
Django                   Prestige 7057       jazz
Flight to Denmark        SteepleChase 1011   jazz
Hi-Fly                   New Jazz 8273       jazz
Waltz for Debby          Riverside 9399      jazz
%
とします。
(編集注: texが複雑過ぎて良く分からなかった。たぶんこうだと思う、という風に整形したが…)

固定長レコードからの変換

固定長レコードフォーマットに変換してしまったファイルを、元のデータベースフォーマットに戻す一般的な方法は存在しないのですが、通常は
expand ファイル名| sed -e 'y/ /_/' -e 's/___*/ /g'」
で戻せることが多いようです。
例えば
% cat table1
Cool Struttin'           Blue Note 1588      jazz
Django                    Prestige 7057       jazz
Flight to Denmark         SteepleChase 1011    jazz
Hi-Fly                    New Jazz 8273       jazz
Waltz for Debby          Riverside 9399      jazz
% 
というファイルtable1をデータベースフォーマットに変換するには
% expand table1 | sed -e 'y/ /_/'  -e 's/___*/ /g'}
Cool_Struttin'  Blue_Note_1588 jazz
Django Prestige_7057 jazz
Flight_to_Denmark SteepleChase_1011 jazz
Hi-Fly New_Jazz_8273 jazz
Waltz_for_Debby Riverside_9399 jazz
% 
で可能です。
(編集注: ここも元のtexが複雑過ぎて良く分からなかった)

おわりに

この冊子では「リレーショナルデータベースにおける1操作を1ラインで済ませる」という視点からUnixのコマンドを紹介しました。
Unixには、ここで紹介した以外にも非常に多くのテキスト操作コマンドがあり、多彩なテキスト操作ができるようになっています。
またここに紹介したコマンドについても、もっと多くの応用的な使い方が存在します。

この冊子が皆さんのUnixへの興味を少しでも喚起することになれば幸いです。

タグ:

+ タグ編集
  • タグ:

このサイトはreCAPTCHAによって保護されており、Googleの プライバシーポリシー利用規約 が適用されます。

最終更新:2012年01月23日 06:51
ツールボックス

下から選んでください:

新しいページを作成する
ヘルプ / FAQ もご覧ください。