ARGV - みる会図書館


検索対象: UNIX MAGAZINE 1996年10月号
5件見つかりました。

1. UNIX MAGAZINE 1996年10月号

PortabIe Programming ■ 表 1 アプリケーション・コンポーネントとその樹直性 コンポーネント 移植性にかかわる問題 例 OS メモリ管理 メモリの割当てと解放 メモリ境界の大きさ メモリを参照するのはポインタか、ハンドルか オープン / 読み / 書き性能 同時にオープンできるファイル数 ディレクトリの検索 パス / ファイル情報 ディレクトリ・セパレータ ( / か \ ) 利用できるタイマーの数 タイマーの分解能 異なったディスプレイ・タイフ。の扱い 不舞直しやすい画像フォーマット ターゲットとするプラットホームの色数 ターゲットとするプラットホームのフォント 存在しないフォントの扱い ターゲット・プラットホーム上のウインドウサイズやその変更 ディスプレイの解像度や利用可能なフォントの違いによる GUI オプ ジェクトのサイズや配置 ターゲットとするプラットホームの描画能 XDrawLine グラフィック・コンテキストの処理 Graphics Contexts ホットキーのサポート Primary 、 Secondary Select ions PostScript もしくはネイテイプのプリントドライバのサポート オプジェクト固有のイベント イベントのタイプ、メッセージ機能 ウインドウのサイズや配置 ターゲットとするプラットホームへの M 。 tif オプジェクトのマッピ ング ヘルプの構築と展開 できれはネイテイプなサーヒ、スを使う。そうでない場合は自前のサー ヒ、ス ターゲットとするプラットホームて利用可能かどうか 他のトランスポートに適合したトランスポート独立型 API の作成 複数のプラットホームでのサポート C 実彳ライプラリがかならすしも同一ではない 異なる文字セットの扱い ターゲットとするプラットホームでの多言言韶 ) サポート タイムゾーンが使えるか否か argc と argv が使えるか否か ( オプションの指定方法の違い ) 工ンディアンの問題 malloc free fopen fread fwrite 屯な I/O サー ピス タイマー ウインドウ・システム 画像とカラー Pixmaps XA110CC010r XLoadQueryFont XFontStruct フォント ディスプレイの解像度 ジオメトリ管理 描画機能 クリップポード交換 印刷 GUI イベント ウインドウ操作 GUI オプジェクト管理 プラットホーム・サービス オンラインヘルフ・システム j 尺ウインドウ ( ファイル、 カラー フォント、 スタイル、サーピス ) ネットワーク・システム トランスポート層 データベース データベースに依存しないアクセス データ構告 文字列 XEvent XMapWindow TCP/IP strcmp 変 のタ 日 time argc 、 argv 84 UNIX MAGAZINE 1996 ユ 0

2. UNIX MAGAZINE 1996年10月号

連ü/PERL ADVISOR— 136 北けこのだが、両者を混司しないように灑愚しよう。 1 UNIX の grep コマンドにイ以たをもっているのでこのように命名さ 的に $ ーに設定してからプロックを言叫面する。プロックが grep 演算子はリストの各要素に対し、その要素を一時 の処理も簡単にできる。 を -T 演算子て調べればいい。 grep 演算子 1 を使えば、こ ストかバイナリかを知るためには、それぞれのファイル名 @ARGV はすべてのファイル名を含んでいるので、テキ ていはうまくいくが、ときに間違う場合もある。 バイナリファイルかを擱則しようとする。この孑則はたい イルからバイト列を取り出し、それがテキストファイルか イナリかを示す属性 &f 尉寺していないので、 PerI はファ を返す。現在の UNIX は、あるファイルがテキストかバ ハンドルの示すファイルが、テキストファイルであれは真 引数に指定した文字列 ( ここではファイル名 ) やファイル PerI の組込み演算子 -T を使えは簡単だ。この演算子は、 ナリファイルとテキストファイルの区別である。これは、 げられないかを考えてみよう。最初にすべきことは、バイ こで、 Perl で書いた grep を textgrep にイ上立てあ リファイルから探されては困るからだ。 立つ。ソースファイルから文字列を探したいのに、バイナ れている。そのような場合も、 textgrep が使えれば役に ファイルとオプジェクト・ファイルが入り交しって置か コンパイル作業中のディレクトリには、数多くのソース % textgrep 文字列 * % cd $HOME/ . bin 実行したいことがある。 えば次のようにこれらのスクリプトに対してだけ grep を 半は Perl で書かれている ) のほうが多い。そこで、たと が、テキストファイル形式の実行可能スクリプト ( その大 /. bin には、バイナリ・プログラムもいくつか置いてある 私刎固人的な、、バイナリ " 用ディレクトリである $ HO るのだ。 イルを無視して、テキストファイルだけを検索の対象とす そして、この魔法のような textgrep は、バイナリファ % textgrep regex * に書ければ便利にちがいない。 ろうと同じように胙する。多くの場合、次のように単純 イルがテキストファイルであろうとバイナリファイルであ システムに付属の grep コマンドは、引数に指定したファ 真を返すような要素については、その要素が grep 演算子 の戻り値として返される。したがって、とりあえすは次の ように書ける。 @ARGV = grep { —T } @ARGV; ( ハイフン ) が ただし、リスト @ARGV のどこかに 含まれていると、このコードは正しく重川しない。この場 ーは標準入力からの読込みを意味する ( ここでは、 標準入力はテキストであると仮定する ) 。ところが、 -T は 有在しないファイルとみなして受け付けないので、これを 区別しなけれはならない。これはそれはど難しくはない。 @ARGV = grep { —T or $ ー eq " } @ARGV ; こうすれば、 @ARGV に含まれるのはテキストファイル だけになる。しかし、もう 1 つ牛未な場合を扱わなけれは ならない。もとのリス日ンヾイナリファイルしか含まれて いないと、新しい @ARGV が空になってしまう。このとき、 プログラムは標準入力から読み込もうとしてしまう。完成 したプログラムでは、私は次のようにしてこの間題に対処 ーー 0 # ! /usr/bin/perl $search = shift ; $showname = @ARGV > 1 ; @ARGV = ”ー unl e s s @ARGV ; @ARGV = grep { —T or $ ー eq exit 0 unless @ARGV; while ( く > ) { next unless /$search/o; ー } @ARGV; print " $ARGV : " if $showname ; print ; 4 行目で、 @ARGV か空なら ーだけを含むリストに置 き換えている。これでコードの意味自体か変わるわけでは ないが、 ( grep 演算子を実行した ) あとで元のリストカ啌 になったかどうかを調べることができる。 5 行目では、さきはど説明したようにテキストファイル だけを残している。 6 行目では、調べるファイルがなくて リストカ啌になっていれば、プログラムを終了する。プロ グラムの残りの部分は変えていない 2 。 これで、 textgrep とヾるようなプログラムができた。 このプログラムは、 -n や -l などのオプションはとらない。 ただし、ファイルのリスト中の、、一 " は標準入力であると解 2 ファイル名カ甘定されなかった場ま、標入力をカけ、 - " を@ARGV に 代入してテストを簡単にしている。 UNIX MAGAZINE 1996.10

3. UNIX MAGAZINE 1996年10月号

連載 /PERL ADVISOR— る行を含むすべてのファイルを編集するには、次のように ト・ディレクトリのなかで、 fred に一致する文字列のあ 利用して処理をおこなう場合に便利だ。たとえば、カレン 1 回だけ表小する。この機能は、 grep コマンドの出力を すると、一致した行ではなく、一致したファイルの名前を コマンドでは、一 1 オプションカ甘旨定できる。これを指定 もうすこしさきに進むとしよう。 UNIX の標準の grep マンド出力の利用 している ) 。 釈する ( 標準入力はつねにテキストファイルであると仮定 すればいい。 % vi grep ー 1 fred * ( 同様に、これらのファイルをディレクトリ に移重丿けることもできる。 % mv grep ー 1 fred * ( 冖 /freds . /freds そこで、 textgrep にもこれと同じ機能を追加すること にしよう。このコードは次のようになる。 # ! /usr/bin/perl $names + + , shift if $ARGV [ 0 ] $search = shift ; $showname = @ARGV > 1 ; @ARGV = " ー unless @ARGV ; @ARGV = grep { —T or $ ー eq exit 0 unless @ARGV; while ( く > ) { next unless /$search/o; if ($names) { print "$ARGV\n" c10se(ARGV) ; } else { print "$ARGV : print ; このために追加したのは、 if 1 " " } @ARGV; eq $ showname ; たった 6 行だけだ。この追 加した部分をみてみよう。 2 行目では、 ( 最初の引数の ) $ARGV [ 0 ] を調べる。こオゞー 1 と等しければ、名前だけ を表小するモードにしたいので、 $names を設定し、一 1 を @ARGV から取り除く。ー 1 以外のものは正規表現であると 仮定しているため、コードの次の行でこれを取り出す。 もう 1 つの変更箇所はダイヤモンドループの内側で ある。正規表現に一致する行がみつかったら、もう一度 UNIX MAGAZINE 1996.10 $names をチェックする。もし真ならば、ファイルの名 前と改行を表示して、 ARGV を閉じる。 ARGV を閉じると、 ルーフ。の寬こ到達するときに、ダイヤモンド演算子は自 動的に次のファイルへと進む。一致する行がみつかると、 ( ファイル名は 1 回しか表示しないので ) ファイルの残り の部分をチェックしても意味がない。こうしておけば、フ ァイル内に一致する行がいくつあっても、ファイル名は 1 回しか表示されない。 $names が偽ならは、一 1 オプションは指定されなか ったことになるから、 else プロックのなかで、以前の textgrep プログラムと同しように重川乍する。 このプログラムがあれば、テキストファイルだけを調べ ■ Randal L. Schwartz ク ) 、 fProgramming PerlJ (Larry Ⅵ第 11 との共著。邦訳 : j 匠藤嘉 に fLearning PerIJ ( 邦訳 : 近藤嘉・雪気尺「初めての PerIJ ソフレヾン UNIX のコンサルティングや Perl に関する日をおこなっている。著書 17 年以 . 日こわたってコンピュータ・サイエンスにかかわり、全米各地で、 ただけたらさいわいである。 し助日した。このような、短いテキスト処理を楽しんでい 勺な UNIX のユーティリティを作りなおし、イ寸加機能 このように、ヨ - ・数行はどの PerI のコードを使って、 イルだけになる。 ないので、結 : にプリンタに送られるのはテキストファ textgrep はテキストファイル以外のファイルを受け付け 指定したすべてのファイルについて真になる。しかし、 は行頭に一致する。これは、普通は grep の引数に % pr 'textgrep ー 1 , * ( ー lpr -Ps1atewriter に出力したいときにも利用できる。 あるいは、たんなるテキストファイルをすべてプリンタ % vi 'textgrep ー 1 fred * ( すればいい。 むテキストファイルだけを編集したい場合は、次のように ることができる。したがって、たとえば文字列 fred を含 ◎ 1996 , UNIX REVIEW (). S. A. ) UNIX REVIEW 1996 年 7 月号より 「 Recognizing Text 」 雪 ( rperl プログラミンみソフトバンク ) がある。 137

4. UNIX MAGAZINE 1996年10月号

PERL ADVISOR ⑨ テキストの識別 RandaI し . Schwartz 0 襯 UNIXREVIEW PerI のテキスト処理機能を利用すれば、いくつかの複 雑な処理を簡単に実行できる。しかし、手にしたテキスト をどのように処理するかよりも、データからテキスト以外 の要素をいかに取り除くかカ墹題になることがある。今回 は、よくあるイ業を簡単にするために、テキストファイル を ( バイナリファイルと ) 区別する Perl の機能をどう活 用すればいいのかをみてみよう。 ます、標準の UNIX コマンドである grep に似た働き をするもっとも簡単なプログラムを作ってみる。 # ! /usr/bin/perl $search = shift ; $showname = @ARGV > 1 ; while ( く > ) { next unless /$search/o; print "$ARGV : " if $showname ; print ; ヘッダ ( # ! で始まる行 ) の次の行では、 1 番目のコマ ンド行引数 (@ARGV に入っている ) を取り出し、変数 $search にオ内する。これは、 shift 演算子のデフォル トが @ARGV だということを利用している。 その次の行では、もし 1 つ以 E の引数カっていれは、 変数 $showname にそのことを求しておく。これによっ て、 grep コマンドと同しように、一致した行とともにファ イル名を表示できる。 $showname は、引数が 1 つ以上な ら真 (true) になり、なければ偽 (false) になる。 お次は、お劇染みのダイヤモンド型のループである。コ マンド行に指定された各ファイルから 1 行すっ読み込み、 それを変数 $ ーロタし、ループの本体でこれに対する処 理をおこなう。 ループの最初の行は $ ーのなかから (PerI の正規表現と UNIX MAGAZINE 1996 ユ 0 して解釈される ) $search を探す。もしみつからなけれ ば、次の行 (next) に進む。正規表現の後ろにあるモディ ファイア。は、速度の最適化を意味する。これがなけれ ば、正規表現はループを実行するたびにコンパイルされて しまい、 ( 正規表現はループ中で変化しないので ) 速度の いたすらな低下を招く。 さらに、変数 $showname か調べられる。これが真な ら、出力する行のう頁に、その行がみつかったファイルの 名前を表小する必喫がある。さいわい、 PerI はスカラー変 数 $ARGV にファイル名をオ翻タしている ( 酉リ @ARGV に 対してファイルハンドル ARGV か設定される際にファイ ル名か第殳定される ) 。 最後に、ファイル名が表示された ( または表示されなか った ) あとに、現在の行 (print 演算子がデフォルトで表 示する $ ー ) を表示する。 したがって、この小さなプログラムは UNIX の grep コマンドのもっとも叫屯な実行形式を、、真似て " 、 grep と 同しように呼び出される。 grep ge ェ [file ... ] ある種の正規表現については、このプログラムのはうが べンダーから提供される grep コマンドより速く重川乍する ようだ。これは、 Perl が内部で使っている正規表現のル ーチンがもっとも高速なルーチンのうちの 1 つだからで ある。 r: = = 加対 grep コマント ところで、私はなぜわざわざ grep コマンドを書きなお したのだろうか。そう、これに機能を追加できるからだ。 135

5. UNIX MAGAZINE 1996年10月号

譬寺集 図 17 横分割 ! 新 ff FiIe Edit 樞 lp Superman ære able 団 willing to prevent evi-L 和 d do 8. If Superman 町目 ble prevent evi.l, 物 d irrmtent; if were 山 i 」ユ i to prwent evil, 知 d malevolent. Su 竄 1 does prevent eviL If S 劇 1 exists, reitIET imgotent mr 1 olent. 愑 2f0 工 Superman does mt exist. ードは朝 . ちををすぎを If 5 ロ】Ⅳ able 町 w 」」ユし 0 prevent 矼 d dO 8. If S 11T 刷 1 unable pmænt 江物 d ) nt ; ⅱ団Ⅱ tO prevent evil, 和一 1 ℃ lent. Su 1 dces mt preænt 自工 If Su 11 1 , reith.r imptent. ror malewlent. if Ⅲ il Ⅱ to prevent evi-l,$ if [ i 」 to prevent i TYEtefore, Superann dæs mt exist. 新第 : を 2. t.xt, 図 18 縦にも割ってみましよう 5 モーレッ UN Ⅸ 図 19 こんなに割れた ff 印、 3 日 ie Edit 題 lp Superman f Super1tuan If Supeman $ Superman ære if 雇 were [ ・ f were 町 i Ⅱ $ f S ℃明 existå If Su 照劇 1 氏 S If Supernan ære if were 町糾・ dces rnt llf sur..l 、 were 節 le 団ⅵ W11. If S 龜 were b to p1MEnt $ if were 謝 i 週い prevent evi ム $ Supertan dces mt prevent eviL If Superman exists, it でミ叩 $ Therefore Sup:erman dæs mt exist. f Supe1hIl.an were able 団 w 石・ to pr$\ f Supeman were unable to prevent evi.l} f were 町 il Ⅱー場 tO prwent 03i 通に創 1 d03S mt prevent evi-l f S を刊 1 exists, neither impotå herefore, S Ⅱ劇 1 dces mt exist. iif S 襞℃Ⅲー f Ⅱ圖 1 ;f リ m ユ ; u I れ dæs not 羽 f Supernan exist$} Superuå 図 20 砂」 ffers ~ は心 : t. を可 :. わ靆 カーソルの動き方 File• Edit•題 lp 'f 靆 SurrmtT f if Surmå eer f Su ロ 1 肥聞 3 = f were i リ士 dæs mt på」 げ Supeman exists ーー沖ⅱ : な 4 f 5 F ile Edit 距 lp Su 斑一 able 団 wi-l-l-ing If Suvemnan 肥町 le 切 S Ⅲ劇 1 dczs prevent evi-L If S 邯 0 Ⅶ 1 exists, her i 叩 Tlmefore, SupertLan dces mt exist. t そ 2. ty.t, f able 劃ⅵ w ユ土瑠 tO pr$ If S リ劇 1 山 ble tO prevent 印Ⅱ 3 釭肥Ⅱル引 1 does mt pzv•ent evi-l. f S 劇 1 exists, neitlzr Therefore, S 囮 n dces mt exist. ""MlL.lf:,: : 良 : tz txt 1 2 - 1 を . - 卩 ln ト : 3 5 ー鬥ⅵ二 If S ℃Ⅲ】 able 町 tO preuent 部 1 去 d dO 8. If S1-ærtnan were 追 ble to は nt 印江し ld impotent; if [ 1 切 prevent evil, 物直 d mlevolent. Surrman dæs mt prevent eviL If Su [ 調れ exists, it } 肥工 impotent ulevolent. TFerefore, Surrman dczs mt exist. にする ( カーソルが次のウインドウへ移動ける ) 。 C-x o ( 小文字オー ) : 次のウインドウお尺ウインドウ C-x 0 ( 数字ゼロ ) : j 尺ウインドウを消去する。 C-x 1 : 尺ウインドウ以外を消去する。 C-x 3 . 〕尺ウインドウを縦に 2 分割する。 ( Fu 朝气にいト鋓Ⅱー ~ は二 t 叮 . txt UNIX MAGAZINE 1996.10 るウインドウをウインドウ、そのバッフアを尺パッ の一日則のウインドウにカーソルがあります。カーソルのあ 意してはしいのがカーソルの位置です。 2 分割されたうち を入力し、画面を横に 2 分割したのか図 17 です。図て注 最初の状態を図 16 ( 1 ) とします。この状態で C-x 2 ウインドウの分割 刎動きを見ていきます。 分かるでしよう。ここでは、簡単な例を使って各コマンド ー己のコマンドを順に試していけは、だいたいのことは する。 C-x 5 0 ( ネゼロ ) : 選択されているフレームを消去 C-x 5 2 . フレームを用意する。 ヨ呶江 e . :i:scrat_.L'h* 7 --t•11.L1e : 6 9 ヨ加 1 二 フアと呼びます。 MuIe に対して実行するアクションは、 尺ウインドウを変更するためのコマンドです。図 20 を C-x 0 ( 小文字オー ) は、複数開いたウインドウ上で 思えは・ここまでうリできてしまうという例です。 い。こんな使い方をする人はいないでしようが、やろうと よく編集できるようになっています。図 19 を見てくださ このように、ウインドウを縦横自由自在に分割し、効率 が ; 尺ウインドウになっています。 分割した様子です。 j 尺ウインドウカ礙にうリさ左 . E 図 18 は、図 17 の状態から C-x 3 でウインドウを縦に いうメッセージがエコー領域に表示されます。 それ以上分割できない場合は、、 Args out of range" と ではなく、ある程度行数がなけれは分割してくれません。 す。これを繰り返せばどんどん分割されていく・・・・・・わけ ンドウ ( 上側のウインドウ ) がさらに横に 2 分割されま 図 17 の状態でもう 1 度 C ー x2 を入力すると、〕尺ウィ すべて尺ウインドウに対して有効です。 51