「Unixコマンドで作るリレーショナルデータベース」の編集履歴(バックアップ)一覧はこちら
追加された行は緑色になります。
削除された行は赤色になります。
オリジナルはこちら
http://kanji.zinbun.kyoto-u.ac.jp/~yasuoka/publications.html
latexデータだといろいろ使いまわしがきついので、atwikiにキーボードマクロで変換してみました。
ライセンスの扱いが良く分からなかったので、もし問題ならhogeika2@gmail.comまで連絡お願いします。
|title|Unixコマンドで作るリレーショナルデータベース|
|author|安岡孝一|
|place|漢籍担当職員講習会|
|type|「Unixと情報検索」資料|
|date|1994年10月6日(木)|
*はじめに
Unixにはリレーショナルデータベースを構築するためのコマンドがほぼそろっており、
リレーショナルデータベースにおける1操作が1ラインで済むようになっています。
すなわちUnixでは、
めんどくさいプログラムを組むことなく、
個人用のデータベースを簡単に作ったり使ったりできるのです。
この冊子では、
それらのコマンドを使用例とともにまとめてみました。
皆さんがデータベースを作る際の手助けとなれば幸いです。
*Unixの基礎
この章では、
この冊子を読むにあたって、
最低限必要なUnixに関することがらについて述べます。
Unixについて一通りの知識のある方は、
読みとばして下さってかまいません。
なお以下では、
キーボードから打ち込んだ文字列にはアンダーラインを引いて表します。
(defun space-all()
(interactive)
(save-excursion
(beginning-of-buffer)
(insert #\SPC)
(while (next-line 1)
(beginning-of-line)
(insert #\SPC)
)
(beginning-of-line)
(insert #\SPC)
)
)
** ファイルの一覧表を出力する
ファイルの一覧表を出力するコマンドは「&tt(){ls}」です。
\% \underline{ls}\\
personnel title1 title2\\
\% \cursor
** ファイルの内容を出力する
ファイルの内容を出力するコマンドは「&tt(){cat} ファイル名」です。
\% \underline{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\\
\% \cursor
** 出力をファイルに取り込む
コマンドの出力をファイルに取り込むには、
コマンドの後に「&tt(){>}ファイル名」とします。
これにより、いかなるコマンドの出力もファイルに取り込めます。
\% \underline{ls > tmp}\\
\% \underline{cat tmp}\\
personnel title1 title2 tmp\\
\% \cursor
*データベースファイル
** フォーマット
この冊子で用いる表形式のリレーショナルデータベースファイルは、
以下のようなフォーマットとなっているものです。
+ 1行=1レコード
+ 各レコードが同一数のフィールドを持ち、フィールドの区切りは空白1つである
+ フィールド内の空白はアンダーラインに置き換える
例えば
\begin{tabular}{|l|l|}\hline
Cool Struttin' & Blue Note 1588 \\ \hline
Django & Prestige 7057 \\ \hline
Flight to Denmark & SteepleChase 1011 \\ \hline
Hi-Fly & New Jazz 8273 \\ \hline
Waltz for Debby & Riverside 9399 \\ \hline
\end{tabular}
という表は、
次のような内容を持つデータベースファイルで表されます。
Cool\_Struttin' Blue\_Note\_1588\\
Django Prestige\_7057\\
Flight\_to\_Denmark SteepleChase\_1011\\
Hi-Fly New\_Jazz\_8273\\
Waltz\_for\_Debby Riverside\_9399
** 正規化(normalization)
上記のフォーマットに従ったファイルでも、
同一のレコードがあったりすると正常な処理が行なえません。
そこで処理にさきだってファイルを正規化する必要があります。
ファイルを正規化するコマンドは「&tt(){sort -u} ファイル名」です。
例えば
\begin{tabular}{|l|l|}\hline
Waltz for Debby & Riverside 9399 \\ \hline
Django & Prestige 7057 \\ \hline
Cool Struttin' & Blue Note 1588 \\ \hline
Flight to Denmark & SteepleChase 1011 \\ \hline
Hi-Fly & New Jazz 8273 \\ \hline
Cool Struttin' & Blue Note 1588 \\ \hline
\end{tabular}
という表、すなわち
\% \underline{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\\
\% \cursor
というファイル&tt(){illegal}を正規化すると
\% \underline{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\\
\% \cursor
すなわち
\begin{tabular}{|l|l|}\hline
Cool Struttin' & Blue Note 1588 \\ \hline
Django & Prestige 7057 \\ \hline
Flight to Denmark & SteepleChase 1011 \\ \hline
Hi-Fly & New Jazz 8273 \\ \hline
Waltz for Debby & Riverside 9399 \\ \hline
\end{tabular}
という表になります。
*データに対する操作
この章では、
リレーショナルデータベースにおける基本的操作それぞれについて、
対応するUnixコマンドを紹介します。
** 結び(union)
2つのファイルの結びをとるコマンドは「&tt(){sort -u} ファイル名 ファイル名」です。
例えば
\begin{tabular}{|l|l|}\hline
Cool Struttin' & Blue Note 1588 \\ \hline
Django & Prestige 7057 \\ \hline
Flight to Denmark & SteepleChase 1011 \\ \hline
Hi-Fly & New Jazz 8273 \\ \hline
Waltz for Debby & Riverside 9399 \\ \hline
\end{tabular}
という表(ファイル&tt(){title1})と
\begin{tabular}{|l|l|}\hline
Django & Prestige 7057 \\ \hline
Groovy & Prestige 7113 \\ \hline
Portrait in Jazz & Riverside 1162 \\ \hline
Speak Low & Jazztime 002 \\ \hline
The Bud Powell Trio & Roost 401 \\ \hline
Waltz for Debby & Riverside 9399 \\ \hline
We Three & New Jazz 8210 \\ \hline
\end{tabular}
という表(ファイル&tt(){title2})との結びをとるには
\% \underline{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\\
\% \cursor
とします。
これによって2つの表の結びである
\begin{tabular}{|l|l|}\hline
Cool Struttin' & Blue Note 1588 \\ \hline
Django & Prestige 7057 \\ \hline
Flight to Denmark & SteepleChase 1011 \\ \hline
Groovy & Prestige 7113 \\ \hline
Hi-Fly & New Jazz 8273 \\ \hline
Portrait in Jazz & Riverside 1162 \\ \hline
Speak Low & Jazztime 002 \\ \hline
The Bud Powell Trio & Roost 401 \\ \hline
Waltz for Debby & Riverside 9399 \\ \hline
We Three & New Jazz 8210 \\ \hline
\end{tabular}
を得られます。
** 差(difference)
2つのファイルの差をとるコマンドは「&tt(){comm -23} ファイル名 ファイル名」です。
これにより、
前のファイルにあって後のファイルにないレコードを選び出せます。
例えば
\begin{tabular}{|l|l|}\hline
Cool Struttin' & Blue Note 1588 \\ \hline
Django & Prestige 7057 \\ \hline
Flight to Denmark & SteepleChase 1011 \\ \hline
Hi-Fly & New Jazz 8273 \\ \hline
Waltz for Debby & Riverside 9399 \\ \hline
\end{tabular}
という表(ファイル&tt(){title1})と
\begin{tabular}{|l|l|}\hline
Django & Prestige 7057 \\ \hline
Groovy & Prestige 7113 \\ \hline
Portrait in Jazz & Riverside 1162 \\ \hline
Speak Low & Jazztime 002 \\ \hline
The Bud Powell Trio & Roost 401 \\ \hline
Waltz for Debby & Riverside 9399 \\ \hline
We Three & New Jazz 8210 \\ \hline
\end{tabular}
という表(ファイル&tt(){title2})の差をとるには
\% \underline{comm -23 title1 title2}\\
Cool\_Struttin' Blue\_Note\_1588\\
Flight\_to\_Denmark SteepleChase\_1011\\
Hi-Fly New\_Jazz\_8273\\
\% \cursor
とします。
これによって2つの表の差である
\begin{tabular}{|l|l|}\hline
Cool Struttin' & Blue Note 1588 \\ \hline
Flight to Denmark & SteepleChase 1011 \\ \hline
Hi-Fly & New Jazz 8273 \\ \hline
\end{tabular}
を得られます。
** 重なり(intersection)
2つのファイルの重なりをとるコマンドは
「&tt(){comm -12} ファイル名 ファイル名」です。
例えば
\begin{tabular}{|l|l|}\hline
Cool Struttin' & Blue Note 1588 \\ \hline
Django & Prestige 7057 \\ \hline
Flight to Denmark & SteepleChase 1011 \\ \hline
Hi-Fly & New Jazz 8273 \\ \hline
Waltz for Debby & Riverside 9399 \\ \hline
\end{tabular}
という表(ファイル&tt(){title1})と
\begin{tabular}{|l|l|}\hline
Django & Prestige 7057 \\ \hline
Groovy & Prestige 7113 \\ \hline
Portrait in Jazz & Riverside 1162 \\ \hline
Speak Low & Jazztime 002 \\ \hline
The Bud Powell Trio & Roost 401 \\ \hline
Waltz for Debby & Riverside 9399 \\ \hline
We Three & New Jazz 8210 \\ \hline
\end{tabular}
という表(ファイル&tt(){title2})との重なりをとるには
\% \underline{comm -12 title1 title2}\\
Django Prestige\_7057\\
Waltz\_for\_Debby Riverside\_9399\\
\% \cursor
とします。
これによって2つの表の重なりである
\begin{tabular}{|l|l|}\hline
Django & Prestige 7057 \\ \hline
Waltz for Debby & Riverside 9399 \\ \hline
\end{tabular}
を得られます。
** 選択(selection)
ファイルから特定のレコードを取り出すコマンドは
「&tt(){awk }' 条件 &tt(){}' ファイル名」です。
条件には以下のものが使用できます。
\vspace*{2ex}
\noindent
\begin{tabular}{rll}
i) & &tt(){\$} フィールド番号 &tt(){=="}文字列 &tt(){"} &
指定されたフィールドが文字列と等しい \\
ii) & &tt(){\$} フィールド番号 &tt(){!="}文字列 &tt(){"} &
指定されたフィールドが文字列と等しくない \\
iii) & &tt(){\$} フィールド番号&tt(){\~{ }/} 文字列 &tt(){/} &
指定されたフィールドが文字列を含む \\
iv) & &tt(){\$} フィールド番号 &tt(){!\~{ }/} 文字列 &tt(){/} &
指定されたフィールドが文字列を含まない \\
v) & &tt(){\$} フィールド番号 &tt(){==\$} フィールド番号 &
指定されたフィールド同士が等しい \\
vi) & &tt(){\$} フィールド番号 &tt(){!=\$} フィールド番号 &
指定されたフィールド同士が等しくない \\
vii) & 条件&tt(){\&\&}条件 & 2つの条件の論理積 \\
viii) & 条件&tt(){||}条件 & 2つの条件の論理和 \\
\end{tabular}
\vspace*{2ex}
例えば
\begin{tabular}{|l|l|l|}\hline
Prestige 7027 & Art Blakey & drums \\ \hline
Prestige 7027 & Percy Heath & bass \\ \hline
Prestige 7027 & Thelonious Monk & piano \\ \hline
Prestige 7057 & John Lewis & piano \\ \hline
Prestige 7057 & Kenny Clarke & drums \\ \hline
Prestige 7057 & Milt Jackson & vibes \\ \hline
Prestige 7057 & Percy Heath & bass \\ \hline
Prestige 7113 & Arthur Taylor & drums \\ \hline
Prestige 7113 & Paul Chambers & bass \\ \hline
Prestige 7113 & Red Garland & piano \\ \hline
\end{tabular}
という表、すなわち
\% \underline{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\\
\% \cursor
というファイル&tt(){personnel}から、
第3フィールドが&tt(){piano}であるものを取り出すには
\% \underline{awk '\$3=="piano"' personnel}\\
Prestige\_7027 Thelonious\_Monk piano\\
Prestige\_7057 John\_Lewis piano\\
Prestige\_7113 Red\_Garland piano\\
\% \cursor
とします。
これによって
\begin{tabular}{|l|l|l|}\hline
Prestige 7027 & Thelonious Monk & piano \\ \hline
Prestige 7057 & John Lewis & piano \\ \hline
Prestige 7113 & Red Garland & piano \\ \hline
\end{tabular}
という表が得られます。
** 射影(projection)
ファイルから特定のフィールドを取り出すコマンドは
「&tt(){join -o} フィールド指定 &tt(){-a1} ファイル名 &tt(){/dev/null | sort -u}」
です。
フィールド指定は「&tt(){1.} フィールド番号」で行ない、
複数のフィールドを指定することが可能です。
例えば
\begin{tabular}{|l|l|l|}\hline
Prestige 7027 & Art Blakey & drums \\ \hline
Prestige 7027 & Percy Heath & bass \\ \hline
Prestige 7027 & Thelonious Monk & piano \\ \hline
Prestige 7057 & John Lewis & piano \\ \hline
Prestige 7057 & Kenny Clarke & drums \\ \hline
Prestige 7057 & Milt Jackson & vibes \\ \hline
Prestige 7057 & Percy Heath & bass \\ \hline
Prestige 7113 & Arthur Taylor & drums \\ \hline
Prestige 7113 & Paul Chambers & bass \\ \hline
Prestige 7113 & Red Garland & piano \\ \hline
\end{tabular}
という表(ファイル&tt(){personnel})から、
第3フィールドと第2フィールドをその順番で取り出すには
\% \underline{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\\
\% \cursor
とします。
これによって
\begin{tabular}{|l|l|}\hline
bass & Paul Chambers \\ \hline
bass & Percy Heath \\ \hline
drums & Art Blakey \\ \hline
drums & Arthur Taylor \\ \hline
drums & Kenny Clarke \\ \hline
piano & John Lewis \\ \hline
piano & Red Garland \\ \hline
piano & Thelonious Monk \\ \hline
vibes & Milt Jackson \\ \hline
\end{tabular}
という表が得られます。
** 結合(natural join)
2つのファイルの第1フィールド同士による結合を行なうコマンドは
「&tt(){join} ファイル名 ファイル名」です。
例えば
\begin{tabular}{|l|l|}\hline
Jazztime 002 & Speak Low \\ \hline
New Jazz 8210 & We Three \\ \hline
Prestige 7057 & Django \\ \hline
Prestige 7113 & Groovy \\ \hline
Riverside 1162 & Portrait in Jazz \\ \hline
Riverside 9399 & Waltz for Debby \\ \hline
Roost 401 & The Bud Powell Trio \\ \hline
\end{tabular}
という表、すなわち
\% \underline{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\\
\% \cursor
というファイル&tt(){revtitle2}と
\begin{tabular}{|l|l|l|}\hline
Prestige 7027 & Art Blakey & drums \\ \hline
Prestige 7027 & Percy Heath & bass \\ \hline
Prestige 7027 & Thelonious Monk & piano \\ \hline
Prestige 7057 & John Lewis & piano \\ \hline
Prestige 7057 & Kenny Clarke & drums \\ \hline
Prestige 7057 & Milt Jackson & vibes \\ \hline
Prestige 7057 & Percy Heath & bass \\ \hline
Prestige 7113 & Arthur Taylor & drums \\ \hline
Prestige 7113 & Paul Chambers & bass \\ \hline
Prestige 7113 & Red Garland & piano \\ \hline
\end{tabular}
という表(ファイル&tt(){personnel})の結合をとるには
\% \underline{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\\
\% \cursor
とします。
これによって
\begin{tabular}{|l|l|l|l|}\hline
Prestige 7057 & Django & John Lewis & piano \\ \hline
Prestige 7057 & Django & Kenny Clarke & drums \\ \hline
Prestige 7057 & Django & Milt Jackson & vibes \\ \hline
Prestige 7057 & Django & Percy Heath & bass \\ \hline
Prestige 7113 & Groovy & Arthur Taylor & drums \\ \hline
Prestige 7113 & Groovy & Paul Chambers & bass \\ \hline
Prestige 7113 & Groovy & Red Garland & piano \\ \hline
\end{tabular}
という表が得られます。
** 拡張(expansion)
ファイルの各レコードに同一内容のフィールドを追加するコマンドは
「&tt(){sed 's/\$/} 文字列 &tt(){/}' ファイル名」です。
例えば
\begin{tabular}{|l|l|}\hline
Cool Struttin' & Blue Note 1588 \\ \hline
Django & Prestige 7057 \\ \hline
Flight to Denmark & SteepleChase 1011 \\ \hline
Hi-Fly & New Jazz 8273 \\ \hline
Waltz for Debby & Riverside 9399 \\ \hline
\end{tabular}
という表(ファイル&tt(){title1})の各レコードに、
&tt(){jazz}という内容のフィールドを追加するには
\% \underline{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\\
\% \cursor
とします。
これによって
\begin{tabular}{|l|l|l|}\hline
Cool Struttin' & Blue Note 1588 & jazz \\ \hline
Django & Prestige 7057 & jazz \\ \hline
Flight to Denmark & SteepleChase 1011 & jazz \\ \hline
Hi-Fly & New Jazz 8273 & jazz \\ \hline
Waltz for Debby & Riverside 9399 & jazz \\ \hline
\end{tabular}
という表が得られます。
*固定長レコードフォーマット
この冊子で用いてきたデータベースフォーマットに従ったファイルは、
Unix上で扱うには非常に便利なものですが、
人間が読むにはあまり適当とはいえません。
そこで一般に読みやすいと思われる、
固定長レコードフォーマットとの変換を考えてみましょう。
** 固定長レコードへの変換
データベースフォーマットのファイルを、
固定長レコードフォーマットに変換するコマンドは
「&tt(){tr ' \_' '$\backslash$011 ' <} ファイル名
&tt(){| expand -} 第1フィールド終了桁&tt(){,} 第2フィールド終了桁&tt(){,}…」
です。
例えば
\% \underline{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\\
\% \cursor
というファイル&tt(){jazztitle1}を、
第1フィールド25文字、
第2フィールド20文字の固定長レコードフォーマットに変換するには
\% \underline{tr ' \_' '$\backslash$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\\
\% \cursor
とします。
** 固定長レコードからの変換
固定長レコードフォーマットに変換してしまったファイルを、
元のデータベースフォーマットに戻す一般的な方法は存在しないのですが、
通常は「&tt(){expand} ファイル名
&tt(){| sed -e 'y/ /\_/' -e 's/\_\_\_$\ast$/ /g}'」
で戻せることが多いようです。
例えば
\% \underline{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\\
\% \cursor
というファイル&tt(){table1}をデータベースフォーマットに変換するには
\% \underline{expand table1 | sed -e 'y/ /\_/' -e 's/\_\_\_$\ast$/ /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\\
\% \cursor
で可能です。
*おわりに
この冊子では
「リレーショナルデータベースにおける1操作を1ラインで済ませる」
という視点からUnixのコマンドを紹介しました。
Unixには、
ここで紹介した以外にも非常に多くのテキスト操作コマンドがあり、
多彩なテキスト操作ができるようになっています。
またここに紹介したコマンドについても、
もっと多くの応用的な使い方が存在します。
この冊子が皆さんのUnixへの興味を少しでも喚起することになれば幸いです。
\end{document}
オリジナルはこちら
http://kanji.zinbun.kyoto-u.ac.jp/~yasuoka/publications.html
latexデータだといろいろ使いまわしがきついので、atwikiにキーボードマクロで変換してみました。
ライセンスの扱いが良く分からなかったので、もし問題ならhogeika2@gmail.comまで連絡お願いします。
|title|Unixコマンドで作るリレーショナルデータベース|
|author|安岡孝一|
|place|漢籍担当職員講習会|
|type|「Unixと情報検索」資料|
|date|1994年10月6日(木)|
*はじめに
Unixにはリレーショナルデータベースを構築するためのコマンドがほぼそろっており、リレーショナルデータベースにおける1操作が1ラインで済むようになっています。
すなわちUnixでは、めんどくさいプログラムを組むことなく、個人用のデータベースを簡単に作ったり使ったりできるのです。
この冊子では、それらのコマンドを使用例とともにまとめてみました。
皆さんがデータベースを作る際の手助けとなれば幸いです。
*Unixの基礎
この章では、この冊子を読むにあたって、最低限必要なUnixに関することがらについて述べます。
Unixについて一通りの知識のある方は、読みとばして下さってかまいません。
なお以下では、キーボードから打ち込んだ文字列にはアンダーラインを引いて表します。
** ファイルの一覧表を出力する
ファイルの一覧表を出力するコマンドは「&tt(){ls}」です。
% ls
personnel title1 title2
%
** ファイルの内容を出力する
ファイルの内容を出力するコマンドは「&tt(){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
%
** 出力をファイルに取り込む
コマンドの出力をファイルに取り込むには、
コマンドの後に「&tt(){>}ファイル名」とします。
これにより、いかなるコマンドの出力もファイルに取り込めます。
% ls > tmp
% cat tmp
personnel title1 title2 tmp
%
*データベースファイル
** フォーマット
この冊子で用いる表形式のリレーショナルデータベースファイルは、以下のようなフォーマットとなっているものです。
+ 1行=1レコード
+ 各レコードが同一数のフィールドを持ち、フィールドの区切りは空白1つである
+ フィールド内の空白はアンダーラインに置き換える
例えば
|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)
上記のフォーマットに従ったファイルでも、
同一のレコードがあったりすると正常な処理が行なえません。
そこで処理にさきだってファイルを正規化する必要があります。
ファイルを正規化するコマンドは「&tt(){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
%
というファイル&tt(){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つのファイルの結びをとるコマンドは「&tt(){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 |
という表(ファイル&tt(){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 |
という表(ファイル&tt(){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つのファイルの差をとるコマンドは「&tt(){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 |
という表(ファイル&tt(){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 |
という表(ファイル&tt(){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つのファイルの重なりをとるコマンドは「&tt(){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 |
という表(ファイル&tt(){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 |
という表(ファイル&tt(){title2})との重なりをとるには
% comm -12 title1 title2
Django Prestige_7057
Waltz_for_Debby Riverside_9399
%
とします。
これによって2つの表の重なりである
|Django | Prestige 7057 |
|Waltz for Debby | Riverside 9399 |
を得られます。
** 選択(selection)
ファイルから特定のレコードを取り出すコマンドは「&tt(){awk }' 条件 &tt(){}' ファイル名」です。
条件には以下のものが使用できます。
|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
%
というファイル&tt(){personnel}から、
第3フィールドが&tt(){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)
ファイルから特定のフィールドを取り出すコマンドは
「&tt(){join -o} フィールド指定 &tt(){-a1} ファイル名 &tt(){/dev/null | sort -u}」
です。
フィールド指定は「&tt(){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 |
という表(ファイル&tt(){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フィールド同士による結合を行なうコマンドは「&tt(){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
%
というファイル&tt(){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 |
という表(ファイル&tt(){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)
ファイルの各レコードに同一内容のフィールドを追加するコマンドは「&tt(){sed 's/\$/} 文字列 &tt(){/}' ファイル名」です。
例えば
|Cool Struttin' | Blue Note 1588 |
|Django | Prestige 7057 |
|Flight to Denmark | SteepleChase 1011 |
|Hi-Fly | New Jazz 8273 |
|Waltz for Debby | Riverside 9399 |
という表(ファイル&tt(){title1})の各レコードに、&tt(){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上で扱うには非常に便利なものですが、人間が読むにはあまり適当とはいえません。
そこで一般に読みやすいと思われる、固定長レコードフォーマットとの変換を考えてみましょう。
** 固定長レコードへの変換
データベースフォーマットのファイルを、固定長レコードフォーマットに変換するコマンドは
「&tt(){tr ' ' '\011' <} ファイル名&tt(){| expand -} 第1フィールド終了桁&tt(){,} 第2フィールド終了桁&tt(){,}…」
です。
例えば
% 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
%
というファイル&tt(){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が複雑過ぎて良く分からなかった。たぶんこうだと思う、という風に整形したが…)
** 固定長レコードからの変換
固定長レコードフォーマットに変換してしまったファイルを、元のデータベースフォーマットに戻す一般的な方法は存在しないのですが、通常は
「&tt(){expand} ファイル名&tt(){| 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
%
というファイル&tt(){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への興味を少しでも喚起することになれば幸いです。