emaCS 入門 があり、ⅵ系にはⅵ、 jvi 、 jstevie などがあります。ま た、 Emacs 系のものにはここで紹介する Nemacs(GNU は、コントロールキーと、、 A クのキーを同時に押すことを意 Emacs) のほか、 jove 、 MicroEMACS 、 kemacs などか 味します。 A" と表記されることもあります。文字 ( 上の あります。 ⅵは、 UNIX 標準のスクリーンエデイタです。 C のプロ 例では A ) は、大文字でも小文字でもかまいません。また、 グラムを書くのに都合よくできているので UN Ⅸプログ M 一文字 ラマーのあいだではファンが多いのですが、残念ながら日 は、メタキ—CMETA" と書かれたキー ) と文字のキーを 本語が扱えません。そこで、ⅵで日本語を扱えるようにし たのが jvi です。日本製の UNIX マシンのⅵも、実際に を同時に押すことを意味します。 は jvi であることが多いようです。 jstevie はつい最近 M-A PDS (PubIic Domain Software) として配られたもので、 かなりよくできたⅵ系の日本語工デイタです。しかも、ソ では、、、 META" キーと、、 A 〃を同時に押します。ただし、 キーポードによってはメタキーがなかったり、たとえあっ ースが入手できるので自分の使っている計算機に移植でき る点も大きな魅力です。 ても使えな 0 、場合があります : そんなときには、 = スケー プキー ( 、、 Escape" あるいは ESC' と書かれたキー ) が代 Emacs はもともとは UNIX 上のエデイタではなかっ わりに使えます。ただしェスケープキーで代用する場合に たのですが、 OS の垣根を越えて多くのファンを集め、いっ は、 ESC キーを押していったん離してから文字を入力して のまにか UNIX 上で動く Emacs も増えてきました。 GNU Emacs 以外にも、次のようなものが PDS として配 ください。、、 M ー A 〃は、 布されています。 ESC A jove: 漢字が使えす、エデイタとしての機能も少ないがと と続けて入力すれば代用できます。 ても負荷が軽い。 このほかに MicroEMACS : jove とはちょっと趣の異なる Emacs く CR> は リターンキー で、やはり漢字は使えす機能も少ないが負荷は軽い。 は ラインフィ ードキー く LF 〉 kemacs : 工デイタとしての機能は小さいが、漢字が使え は デリートキー く DEL 〉 て負荷も軽い。 MicroEmacs を日本語化したもの。 く TAB 〉 は タブキー GNU Emacs や Nemacs も、その名のとおり Emacs を意味しているとします。 系のエデイタです。 コマンド表記のための約束事 さて、これから編集のためのコマンドがいくつも出てき もちろん端木の前まで連れていっ って訊かれたら・・・ て「さあ使ってみて」って言うでしようね。そもそもエデ ますが、キー入力に関して表記上の約束事を決めておきま イタを使いたけれは、 C 一文字 ・ファイルの読込みと保存 は、コントロールキー ( 、℃ ontrol 〃あるいは、℃ TRL" と ・カーソルの移動 書かれたキー ) と文字のキーを同時に押すことを意味しま ・文字の挿入と削除 す。たとえば、 C-A 覚えるための早道は ? 118 UNIX MAGAZINE 1990.9
UN Ⅸへの招待⑩ る番号で注文することにしました。 さて、今月はシェルプログラムにおける変数の使い方に ついて説明します。シェルプログラムでは、 a . one, tWO, ten and ・シェル変数 美女 . Anything else ? ・ユーザーが自分で定義する変数 a . That's a11 . 美女 . Thank you ! という 2 種類の変数が使えます。シェル変数はシェルの起 動時に設定されていますから、シェルプログラムではとく いきなりの英語で緊張、もちろんいっそう疲れが増しま に設定しなくてもその値が使えます。一方、ユーザーが設 した。美女が、、くそギャル〃に見えた梅雨の一夜のことで 定する変数は、自分で設定して値を代入しなければなりま せん。そこで、ます C シェルと Bourne シェルにおける変 数の設定方法をそれぞれ説明しましよう。 変数の設定ー C シェルの場合 いました。現在では、アンダースコアの有無に関係なく最 C シェルにおける変数の設定方法は、シェル変数の設定 と同し set コマンドを使っておこないます。 set は、 大 18 文字となっています 1 。 値には、どのような文字も代入できます。しかし高級言 語とは異なり、変数には型がありません。値はすべて文字 または、 列として扱われます。 set 47 〃 e = 24 / のように使います。 最初の形式では、変数襯召が設定されます。 2 番目の 形式では、変数襯が設定され、値として / が代入さ れます。この形式では、 = の前後に空白を入れないよう注意 してください ( 空白を入れる場合は、前後両方に入れてくだ さい ) 。 set コマンドには、引数をいくつでも指定できま す。したがって、 set 〃 4 川刃〃襯召 2 = 値〃川召 3 = 値 と、いちどに複数の変数が設定できます。 ューザーが定義する変数の名前には、英数字とアンダー スコア ( ー ) が使えます。変数名の長さの制限はシェルのバ ージョンによって異なりますが、 4. IBSD までのシェルで は英数字だけの場合、最大 8 文字まで使えました。アンダ ースコアをあいだに挟めばその前後でそれぞれ 8 文字の英 数字が使えたので、合計 19 文字までの変数名が許されて 1 しつは、この原稿を書くまで、現在は最大何文字になったのかを知りませんで した。書いているときにたまたま隣にいた驕@ astec 氏と一緒に調べてみると、 しつに面白い仕組みになっていました。詳細を知りたい方は、第ワークステーシ ョンのおと″をお読みください。 0 9 H んあ illustration•はらはなこ 150 UNIX MAGAZINE 1990.9
ワークステーションのおと一朝 ・ $ 付きの変数名の方は、どうやら固定長になっている なっているようた。 ・ set のほうは、いくらでも長い名前がとれるように X: ひさしふり。 ss: こんはんわ。 こまで分かったところで、友人に電話しました。 というところが妥当な線のようてす。 らしい。 X: そっちは、やつばり、いくらでもいくようになって ss: set 0 よ ? X : なかで、配列 (sizeof 配列ー 2 ) とかしとるで。 ss:ff げ。それで、なんで 18 文字なんや ? ある。 べるところは、ノくシッと文字の配列で 20 ってとって X : おまえのゆうとったとおりや。 $ 付きの変数名を調 ss : ほんまか。どうやった ? X : 分かったで、わかったで ! ! ( しばらくして ) X : わかった。分かったら連絡するわ。 ちょっと、調べてくれへん ? ( さぎほどの推測を話す ) ss : あのさ、 C シェルの変数の最大長って知ってる ? るわ。 X: foreach のルーフ。のとこで、変数書くやろ。 ss: なんや、なんや。 X : ほんまやな。それと、もう 1 個ええこと教えたろカ ss: ええかげんやな。なんとかしてほしいな。 ss: そういうからには、きっと 18 とか。もしかして X: そこの変数は何文字か分かるか ? ss: うん、うん。 大ポケで 16 とかちゃうやろな。 X : おんなじように 20 とってあるんやけど、判定の仕 と、なかなカれてしまい、宴会に臨むことにしました。 X : やつばりかましてるで。 ss : ほんま力、 ! 方が違うんやな。 19 文字や。 と ころが、ところが、またまた謎は続くのてす 86 しばらくして、手許の C ンエルで foreach の謎を 確認してみることにしました。 csh% foreach X123456789 (a b c) foreach: lnvalid variable . csh% なに ! ? もしかしてこの C シェルやと 10 文字でも あかんてか。 csh% foreach X123 (a b c) foreach: lnvalid variable . csh% え ! ? もしかして、数字が入ってたらあかんとカ うそやろ ? csh% foreach xl (a b c) foreach: lnvalid variable . csh% foreach xx (a b c) ? end csh% なんということでしよう。みごとに、 foreach の直 後の変数には数字が入ったものが使えないではありま せんか。 csh% foreach aaaaabbbbbcccccddddd (a b c) foreach: lnvalid variable . csh% foreach aaaaabbbbbcccccdddd (a b c) csh% 変数名の長さは、やはり 19 文字のようてす。 fo て each の謎は、いろいろな計算機で調べてみると、 1. foreach の直後の変数の最大長は 19 文字 2. 変数名に数字が入ってもよいかどうかは、計算機と その OS のノく一ジョンに依存する ということが分かりました。 さて、後日のこと・・・ ss: こんにちわ。 UNIX MAGAZINE 1990.9
FreeSoftwa 「 e の世界 表 4 m 用の変数 変数 width 1 engt h offset overflowtext overflovoffset compwidth uppercase nouppercase clearscreen noclearscreen be11 nobe11 C omponent nocomponent center 1eftadJust noleftadjust compress nocompress split nosplit formatfield addrfield datefield 型 整数 整数 整数 文字列 整数 整数 フラグ フラグ フラグ フラグ フラグ フラグ 文字列 フラグ フラグ フラグ フラグ フラグ フラグ フラグ フラグ フラグ 文字列 フラグ フラグ 意 画面あるいはヘッダ要素の幅 日付フォーマットであることを指定 アドレス・フォーマットであることを指定 mh - format ( 5 ) によってフォーマットする 複数あるフィールドを 1 つにまとめる 複数あるフィールドをまとめない 変換しない 改行を空白に変換 先頭の空白を削除しない 先頭の空白を削除 中央に合わせない 中央に合わせて出力 ヘッダ名を出力しない ヘッダ名を変更 ベルを鳴らさない ページの最後にベルを鳴らす 画面をクリアしない べージごとに画面をクリア 大文字に変換しない 大文字に変換して出力 ヘッダ内容のインデント幅 ・テキストのインデント幅 オ ・テキストの始まり用の文字列 ヘッダ要素のインデント幅 画面あるいはヘッダ要素の長さ で参照できます。フォーマット・ファイルのなかで extras を出力しないかぎり、 ignores にはなにも指定する必要は ありません。 formatfield の値には、さきほどの mh-format(5) の式 を書くことができます。すると、その要素の中身を指定し たフォーマットにしたがって出力してくれます。 フィールドの幅を指定する変数がたくさんあって、説明 だけではちょっとよく分かりませんね。下に簡単に図解し てみたので見てください。 ところで、日本語を出力するときにはちょっと注意しな ければなりません。 mhl は width を超える行を自動的に 折り返してしまうので、テキストが日本語だといろいろと 問題が生します。漢字コードの 1 バイト目と 2 バイト目の あいだで改行されることがあるからです。 mhl カしく日 0 ガ CO 川〃 w at e : To: ed ′ 11 Ju 1 9 0 11 : 1 9 : 21 srekcah@sra . CO . jp ☆☆☆ over flowed text . Dear, srekcah— UNIX MAGAZINE 1990.9 なん ( g り 本語化されていれば問題ないはすですが、そういうものに はあまりお目にかかったことがありません。無難な回避方 法は、フォーマット・ファイルの body の部分で width= IOOO などのように大きな幅を指定してしまうのがいいで しよう。折返しを防ぐ指定方法はちょっと見つかりません でした。 自分の MH ディレクトリ ( ~ / Ma Ⅱ ) の下に mhl. format というファイルを作っておけは、 mhl はそちらをデフォル トで見るようになるので、自分で好きなようにカスタマイ ズしてみると面白いでしよう。 show コマンドの出力はし ょっちゅう目にするものですから、ちょっとした工夫カ噫 外な視覚的効果をもたらすこともあります。 おわりに さて、いかがでしたか ? 今回説明した 2 つのフォーマッ ト・ファイルを自由に扱えるようになると、 MH の使い方 にもすいぶん幅がでてくると思います。このはかにも、 MH には隠された機能がまだまだたくさんあるので、マニュア ルを片手にいろいろと試してみましよう。メールの管理以 83 外に、思わぬ使い途を発見できるかもしれません。
FreeSoftwa 「 e の世界 80 From: フィールドを表示します。 分で出したものなら To: フィールドを、そうでなければ 調べる関数です。ですから、 From: フィールドをみて自 (mymbox) は、自分のメールアドレスと同しかどうかを 4 ー 5 行目 更新された時刻になります。 す。フィールドがない場合、 { date } の結果はファイルが Date: フィールドがあれば空白、なければ * を表示しま 3 行目 部分に 0 を埋めてくれます。 のように幅を指定すると、 printf と同しように足りない 、、月 / 日クの形で Date: フィールドを表示します。、、 % 02 ' ′ 2 行目 は空白を表示します。 偽になるので、このフィールドがあれは、、ノを、なけれ {replied} は、 Replied: フィールドがあれば真、なければ します。 メッセージならば、、十〃を、そうでなければ空白を表示 1 、そうでなければ 0 を返します。ですから、カレント・ (cur) は、そのメッセージがカレント・メッセージなら 前の 4 で指定しています。 は固定幅で数字を表示するための関数です。幅は関数の ( msg ) でそのメッセージ番号を取り出します。 putnumf 1 行目 では、さきほどのフォーマットを見ていきましよう。 true 、偽なら false を表示します。 く (cur)true% い alse % 〉〃と書けば ( cur ) 関数が真なら 数であれは 0 以外の数値なら真です。たとえば、、、 % 列を返す関数なら空文字列でなけれは真、数値を返す関 実行し、偽であれば % ーから % 〉までを実行します。文字 % くに続く命令の結果が真であればそこから % ーまでを 真ん中の % ーはなくてもかまいません。 れぞれが C シェルでいう if 、 else 、 endif に相当します。 、、 % 〉〃の 3 つが組で使用され、そ です。、、 % ぐ、に 普通のプログラミング言語の if 文にあたる 1 種類だけ ・制御構造 きる文字列は関数によって異ります。 ment dayo ) 〃のように指定します。引数の部分に指定で 引数は命令の後に 1 つ以上の空白を置き、、 % ( lit argu (friendly) は、アドレスをユーザーが読みやすい形に変 換する関数です。 6 行目 %{subject} は Subject: フィールドを表示し、その後に メッセージの本文があれは、、くぐという文字列に続いて 本文を表示します。長すぎる場合には scan コマンドが 適当に切ってくれるので気にする必要はありません。 どうですか、意外と簡単でしよう ? ( ) で囲んで関数を 書くところなどは、 Lisp のシンタックスに似ていますね。 制御構造がちょっと見にくいのが欠点ですが、仕組みさえ 分かってしまえば手に負えないということはなさそうです。 ほかにもたくさんの関数があります。ます一般的な関数 を表 1 に掲けておきます。メッセージに関するもの、演算、 表示、文字列操作など必要そうなものはひととおり揃って います。表 2 は日付を含むフィールドを操作するための関 数です。これらの関数には、引数に日付を表すフォーマッ トしか指定できません。これらの関数を使えば、メッセー ジのなかの文字列から処理しやすいかたちで数値データを 取り出すことができます。 表 3 ( 82 ページ ) はアドレスを操作するための関数です。 アドレスの形式を変換したり、アドレスのなかから文字列 を取り出したり、アドレスリストをメッセージのなかに埋 め込むなどの関数があります。 さて、これでどんな関数があるかも分かったので、さき はどのデフォルト・フォーマットをちょっとカスタマイズ してみることにします。このままでは Date : フィールドは 、、月 / 日〃の形式でしか表示されませんが、 24 時間以内に届 いたメッセージの場合には、、時 : 分〃で表示するようにし てみます。 Date : フィールドと現在時との差を得るために は (rclock) 関数が、 24 時間以内かどうかの判定には (gt) 関数が使えそうです。これらを使って 2 行目をこんなふう に変更してみました。 %(void(rclock{date}) ) % く ( 戚 8640 の \ %02(putnumf (mon{date}) )/%02(putnumf (mday{date}) ) \ 幻 \ 加 2 (hour{date}) : %02(min{date})\ (rclock{date}) で num レジスタには Date: フィール ドと現在時との差が秒単位で入ります。でもそのままだと その数字が表示されてしまうので、それを防ぐために ( v 。 id ) 関数の引数にしておきます。 ( gt ) 関数は num レジ UNIX MAGAZINE 1990.9
連載 Little Language—① です。 GAWK で言当したプログラムをリスト 1 に、ファ イル tl. in を入力した結果をリスト 2 に示します ( 97 ~ 99 ページ : 参 {) 。 ていたグループ名と記事番号を出力した結果を sort 2. 各行を読んで違うグループになったら、これまでメモし んでいって、グループ名と記事番号をメモしておく。 1. ニュースグループとそれに続くニュース id ( 数字 ) を読 コマンドに渡す。 このプログラムのポイントはここにあります (GAWK の構造化オンライン・マニュアル [ 冂と一緒に見ると効果的 BEGIN/END です ) 。 ードのフィールド数を返す ) などがある。 NR は何行目 前述の FS や、ここで使用している NF ( 読み込んだレコ 組込み変数 の意味になる。 できる。これは、糸Ⅲムみ変数 FS をセットしたときと同様 コマンド行から一 F オプションを使って変更することも っておくと、このフィールド・セパレータは GAWK の 空白を使っているが、タブでもよい ) である。ついでにい とになる。フィールド・セパレータは空白 ( この例題では とすると読んだレコードの 3 番目のフィールドを指すこ 示す。 $ 0 は現在読んだレコードすべてを指し、、、 i = 3 : $i" 入力行の一部のフィールドあるいは全部のフィールドを $ 数字 れる。 関数本体で使っているのでローカル変数定義として扱わ なっている。これは実引数としては使用していないが、 定義の仮引数定義のなかで、、、 i 〃という変数の定義をおこ たとえば、リスト 1 中の print-last-group という関数 用できる。 定義できる。仮引数定義部分はローカル変数定義にも使 function で始まるプロックは関数定義である。仮引数も function 々 7 尾 ( ) 処理に使用する特別条件である。 BEGIN と END で始まるプロックは、初期処理と終了 96 のレコードかを表す。 組込み関数 ここでは次の系ムみ関数が使用されている。 substr(string, s , ん〃 g ) : s わ 7 ツ g の s / のプ文字 目から / 翩 g 文字だけ抜き出す。 length (string) : stHng の文字数を返す。 match(string, 尾 g ばカ ) : string と正規表現ゆが 一致するかどうかを調べる。一致条件は最長で、しか も最初にマッチしたものである。 printf: 引数や形式ははとんど UN Ⅸの C と同橋 printf 〉 "/dev/stderr" : フォーマットした結果を標準 出力にプリントする。 print : 引数文字列を出力する。 print は襯心出力した結果をパイプを通して c 川イに 渡す。 close : 引数でなえられたファイルをクローズしたり、あ るいはパイプコマンドを終了する。 文字列の羅列 文字列の連結をおこなう。 記述量がすこし多くなりますが、 GAWK と AWK の パイプ呼出し機能を使用して期待どおりの結果が得られ ました。このプログラムで注目すべき点は、ソート機能を UNIX のコマンドに任せたところと呼び出すべきコマン ドの引数を条件によって変化させていることです。とりあ えずのプロトタイプとして作る目的にはかなっているとい えるでしよう。さらに性能を高めたいのであれば、次に一 ⅱ儿 み進んでください。 解決方法 3 : スピードアップを試みる 膨大な入力データになると、このプログラムの性能が問 題になってきます。そこで、実際のデータから入力ファイ ルを作ってテストしてみました。たとえば、 NEWS 3860 (NEWS OS 3.9R ) 上の GAWK V2.11.1 では、 800 行 におよぶ入力ファイル、、 ls. in 〃を使った場合、次のような 計測結果が出ました。 % time t3. awk ls. in 1.6u 3. ls 0 : 12 40 % 12 + 13k 13 + 433i0 0pf + 0w このプログラムで時間がかかっている部分は、明らかに sort コマンドのところです。ニュースグループの数のぶん UNIX MAGAZINE 1990.9
連載 ZLittIe Language¯① gnews では、保存しておきたい記事をファイルにしまう ときにニュースグループと記事番号からファイル名を決定 し、ホームディレクトリの News の下にセープするように なっています。ファイル名は、たとえは次のような具合に なります。 a1t . sources .55 a1t . sources .667 alt . sources .762 comp ・ comp ・ comp . comp . COITIP . comp . comp ・ comp ・ comp ・ comp ・ archives archives archives archives archives archives archives archives archives archives .1005 .1012 .1093 .110 . 1107 . 1124 . 1171 .118 .1188 .12 このファイルを読むときには、 GN U Emacs の dired (directory editor) という機能が使われます。これは、 ls の結果をもとにファイル操作や編集の機能を提供するも のです。上のような順番でリスト表示されるのはこのため 念のために、簡単に説明しておきます。 でソートしたものを表示するからです。 ードはファイル名を文字コードの昇順 です。つまり、、、 ls sort 十 1 —n キーを数値でソートする。結局、分離した記事番号でソ フィールドを 1 っ飛ばして、数字のフィールドに対して sort 十 1 -n ュースグループと記事番号を分離する。 文字列の前に空白を入れる。つまり、この sed コマンド tl . in のなかで、、、 . 〃から行末まで数字か髞返されている ートすることになる。 UNIX MAGAZINE 1990.9 〃に置き換える。 alt . sources .55 comp. archives. 12 まい、最初に期待したとおりの結果が得られません。 しかし、このコマンドの実行結果は次のようになってし 空白を 、ゝしかし、こでは最後についている数字列を数値とみな し、それを基準に降順あるいは昇順に並べ替えてはしいわ 問題 しようか。 ループごと、 さて、 けです。 値扱いでソーティングして出力するにはどうすればよいで さらに同しニュースグループ内では番号を数 のようにソーティングされたリストを入力し、ニュースグ こで 1 っ間題が提起されました。つまり、上記 覧が入っているファイルを、、 tl . in 〃とし、テスト用の入力 のです。ここで説明を簡単にするために、前例のような一 ムを別フィールドにして数値としてソートする、というも このコマンド列の基本的なアイデアは、数字だけのカラ 次のような組合せが考えられます。 をパイプでつないで処理できそうな気がします。たとえは、 簡単に考えれは・、 sed と sort という UNIX のコマンド 解決方法 1 : sed と sort を使う comp ・ archives. 1188 comp ・ archives. 1171 comp ・ archives. 1124 comp ・ archives. 1107 comp ・ archives. 1093 comp ・ archives. 1012 comp. archives. 1005 alt . sources .762 alt . sources .667 comp ・ archives. 118 comp ・ archives. 110 ファイルとします。 そこで AWK の登場です。 AWK でプログラミングして ープ内でのみおこなわれるようにしなければなりません。 ュースグノレ 動作をさせるには、このソーティングが同しニ ファイルに対して作用してしまうためです。期待どおりの これはなぜかといいますと、 sort コマンドが発体の入力 基本的な考え方は次のようなもので、解決方法 1 と同し 解決方法 2 : GAWK を使う みましよう。 95
emaCS 入門 図幻 C モードのインデント #include く st 0 > main(argc,argv) argc ; char * * 矼空 ; int Ⅱ ; Ⅱ = at 。土 ( 矼空 [ 1 ] ) ; printf ("%d\n" ,factorial(n) ) ; factorial(n) int Ⅱ ; if ( Ⅱ return 1 ; ()f ( = Ⅱ 0 ) (defun factorial (n) (print factorial (n) ) ) (defun print—factori 訌 ( Ⅱ ) 図 22 Lisp モードのインデント return n*factorial(n—l) ; else ←く TAB> を入力すると引数を 8 文字下げる ←く TAB> を入力すると関数中は 2 文字下げる ← if 文中はさらに 2 文字下げる 1 ( * n (factorial ( ーⅡ 1 ) ) ) ) ) ←く TAB 〉を入力すると 2 文字下げる ← ( の数に応じて字下げする を実行した後、 C-x b く CR 〉としてください ( 図 20 ) 。この とき、モードラインは各ウインドウの下に表示されていま す。 ウインドウを分割してファイルを並べてみると・・・・・・ちょ っと違いますね。ん、ファイルの内容が違うのは当り前し ゃないかですって ? いえいえ、ファイルの内容ではなくて モードラインの、、 ( ) 〃内の表示のことです。 main. c のほうでは、 (C) となっていますが、 factorial. el のはうでは、 (Emacs-Lisp) となっています。、、 ( ) 〃内の文字は、しつはバッフアのヾモ ード〃を示しているのです。バッフアに対しては、次の 2 種類のモードが指定できます。 UNIX MAGAZINE 1990.9 メジャーモード マイナーモード バッフアの表示の仕方や入力されたキーの解釈方法を決 定するのが、これらのモード ( とくにメジャーモード ) で す。 main. c のメジャーモードは、℃〃モードで、 factorial. el のはうは、、 Emacs-Lisp" モードです。 たとえは、 main. c の編集中に TAB キーを入力すると 適切な位置までインデント ( 字下げ ) をしてくれたことに 気づいたでしようか ( 図 (1)0 また、 factorial.el を編集し た場合にも、やはり TAB キーを入力することによって Lisp にあった適切なインデントを施してくれます ( 図 22 ) 。 このように、バッフアのメジャーモードに応してインデ ントの仕方を変えてくれるわけです。言い換えれば、 C mode は C 言語の形式を知っていて、 が入力されたら、次の行からはインデントを 1 段深くする とか、 129
FreeSoftware の世界一朝 義するためのファイルです。、、 mhl 〃で始まるのが mhl ( 1 ) をこれから説明しようというわけです。では、ちょっとだ ルのなかで MailAliases 以外はすべてフォーマットを定、ゝフォーマットのファイルです。この 2 種類のフォーマット %{message-id}%>\n%>\ % く (nodate{date})%{date}% l%(tws{date})%>. %<{message-id} % く {date}ln—reply-to : Your message Of \ %<{subject}Subject : Re : %{subject}\n%>\ % く {fcc}Fcc : %{fcc}\n%>\ % く (nonnull)%(void(width) ) %(putaddr cc : ) \n%>\ %(lit) %(fomataddr{to})%(fomataddr{cc})%(fomataddr(me) ) \ % く (nonnull)%(void(width) )%(putaddr To : )\n%>\ %(lit)%(fomataddr % く {reply-to}% 以く {from}% 以く {sender}%l %{return-path}%>%>%>)\ % cat replcomps コマンド用のファイル。それ以外は mh-format(5) という / け覗いてみましよう。 ひやー、まるで暗号ですね。このファイルに近づくには、ゝ好きだったりします。また、 bc よりも dc 、 dbx よりも adb かなりの勇気がいりそうです。実際、かなり MH を使いこ なしているユーザーでも「 replcomps だけには触れるなと いう祖父の遺言で・・・・・・」などという人が少なくないのです。 稀にこのようなファイルが好きだという方もいらっしゃい ますが、そういう人は roff のマクロファイルや send- mail . cf を見るのが趣味で、 sed と m4 でのプログラムが % scan を好む傾向があるようです。 誰も書かなかった mh-format scan コマンドを実行すると、次のような出力が得られま す。 1 07 / 01 ann@oogaboo.oz He110 srekcah ! くく Dear srekcah 2 07 / 02 j inj in@unimaga.co H0110W Tube くく Quox, as you we 3 07 / 06 srekcah@sra. co. JP Re : H0110W Tube くく Hi great th 4 + 07 / 08 ruggedo@nome.co.j Shaggy Man! ! くく Adi , edi , idi , しつは、 scan コマンドは内部的にもっているフォーマツ、、、一マットというのは、次のようなものです。 2 加 2 (putnumf (mon{date}) ) /%02(putnumf (mday{date}) ) \ 1 %4(putnumf (msg) ) % く ( c 矼 ) + 幻 %>% く {replied}\-%l % > \ トにしたがって、このリストを表示しているのです。フォ 3 % く {date} 幻 * % > \ 4 % く (mymbox{from})To : %14(putstrf (friendly{to}) ) \ 5 % l%17(putstrf (friendly{from}) ) % > \ 6 %{subject} % く {body} くく %{body}%> このデフォルトのフォーマットについて説明する前に UNIX MAGAZINE 1990.9 まりです。それぞれのシーケンスは % で始まり、次の 3 種類 フォーマット・ファイルはエスケープ・シーケンスの集 は、そのメッセージの内容を参照することができます。 また、そのとき処理の対象としているメッセージがあれ ます。 命令の種類によってどちらかのレジスタに結果が格納され 保存するために使われます。ある命令を実行すると、その あると考えてください。 str は文字列用で、 num は数値を ます、 str と num という 2 つのレジスタのようなものが 簡単な仕組みについてお話ししておきましよう。 があります。 用意されていて、関数の返す値はレジスタ num か str 示するには、、 % ( puts ) 〃という具合です。多くの関数が これは ( ) で関数名を囲みます。たとえば、 str の内容を表 ・組込み関数の呼出し です。大文字・小文字の区別はありません。 To : フィールドを参照したければ、、、 % { t 。ドという具合 { } でヘッダのフィールド名を囲んで表します。たとえば ・ヘッダの要素の取出し にしまわれます。 79
FreeSoftware の世界 アド アド 表 3 日付処理用の mh - format 関数 関数 proper friendly pers note mbox mymbox host nohost type path formataddr put addr 引数 ア ア ア ア ア ア ア ア 式 ド ド ド ド ド ド ド ド レス レス レス レス レス レス レス レス レス レス 戻り値 文字列 整数 整数 文字列 整数 文字列 文字列 文字列 文字列 文字列 リラ・ラノレ 意味 RFC-822 形式に変換 見やすい形式 ソナルネーム * コメント * ロー - カノレ mailbox* 自分のアドレス ? ( 0 = no 、 l=yes) ホスト部 * ホスト部が存在しない * ホストの型 * (O=IocaI. l=network 、 l=tmcp 、 2 = 不明 ) . パス * 引数のアドレスを str に 追加 str 中のアドレスリスト を引数をラベルにして出 力。幅は num に指定さ れる して使います ( もちろん . mh-profile の showproc: に書 むね次のようなものです。 リ・ディレクトリの下の mhl.format で、この内容はおお mhl のデフォルトのフォーマットは、 MH のライプラ 由に指定できるようになっています。 ジを整えてくれます。しかも、どのように整形するかを自 行を折り返すなどして、ユーザーが見やすい形にメッセー は、このような不必要なフィールドを削ったり、長すぎる ようなフィールドを好んで見たがる人種もいますが ) 。 mhl なんて、ふだんはあまり見たくないものです ( 例外的にこの てあります。 Received: とか Message-ID: のフィールド メールのヘッダを見ると、よけいな情報がたくさん書い て元のメッセージを取り込んでくれます。 ョンを付けると、そこで指定したファイルで mhl を起動し また、返信を送るための repl コマンドに一 filter オフシ するときには mhl を通すようになっています。 ん ) 。 mh-e の半コマンドでメッセージをプリントアウト いておけは、毎回オプションで指定する必要はありませ ( * は、アドレスの最初の要素しか処理しないことを表す ) のコマンドですが、普通はキーポードから直接使うことは lgn. ores=msgid,message—id ,received 3 leftadjust , compwidth=9 2 overflowtext="***'t ,overf10woffset=5 using template mhl. fomat なく、 show コマンドなどの -showproc オプションで指定 13 : 12 11 ・ 9 4 5 Date : fomatfield="% く (nodate{text})%{text}% l%(pretty{text})%>" 6 To : 7 CC From: 10 Subject : extras :nocomponent 14 body:nocomponent ,overf10wtext=,overf10woffset=O ,n01eftadJust さきほどの replcomps よりはすこし親しみやすい気が しますね。このなかには 4 種類の記法があります。 ヘッダ . [ 変数 , ... ] から 4 行目までが該当します。 フォーマット全体に適用される命令です。例では 2 行目 変数 [ 変数 , ... ] セミコロン ( ; ) で始まる行はコメントです。 ; コメント 82 たとえは・ 3 行目で指定してある leftadjust は全体に有 ールドのなかでのみ有効になります。 ッダを出力します。後に命令があると、それはそのフィ 、、ヘッダ : 〃で始まる行があると、その場所に対応するヘ 効な命令ですが、 14 行目の body のなかでは noleftad- just によって無効にすることができます。 : 文字列 〃で始まる行は、その後の文字列がそのまま出力され ます。 : だけの行は空行になります。 どのような変数があるのかを表 4 に示します。フラグ型 の変数は、その変数名を書くだけです。整数型と文字列型 の変数については、変数名と値を、、 〃で結んで指定しま す。文字列はダブルクオート ( " ) で囲みます。見たくない要 素は ignores で指定しておくと表示されません。フォーマ ット・ファイルのなかで指定したヘッダ要素はその場所に 出力され、それ以外の要素はまとめて extras という名前 UNIX MAGAZINE 1990.9