GLOB(7)

glob - パス名を glob する

説明
むかしむかし、 Unix V6 の時代、ワイルドカードパターンを展開する /etc/glob と言うプログラムがあった。その後すぐに、この機能はシェルに組み込まれる ようになった。 今日では、この機能をユーザープログラムでも行えるように、 glob(3) というライブラリルーチンも存在している。 glob の規則を以下に述べる (POSIX 1003.2 3.13)。

ワイルドカードマッチ
文字列に `?', `*', `[' が含まれていると、それはワイルドカードパターン とみなされる。「glob する」というのは、ワイルドカードパターンを展開し て、そのパターンにマッチするパス名のリストを得ることである。マッチは以 下のように定義される。 (ブラケット外部の) `?' はあらゆる単一の文字にマッチする。 (ブラケット外部の) `*' はあらゆる文字列にマッチする。空文字列 (empty string) にもマッチする。

  文字クラス (character class)
`[...]' と言う表記は、先頭の `[' に続く最初の文字が `!' でなければ、ブ ラケットの中に含まれている文字のどれか一つにマッチする。ブラケットの内 部に含まれる文字列は空であってはならない。したがって、 `]' も、最初の 文字に指定すればブラケットの内部に含めることができる。 (つまり `[][!]' は `[', `]', `!' の 3 文字のどれかにマッチする。)

  領域指定 (range)
特殊な表記法が一つだけ存在する。 `-' を挟む二つの文字は、領域指定とな る。 (つまり `[A-Fa-f0-9]' は `[ABCDEFabcdef0123456789]' と等価とな る。) `-' 文字そのものを入れたい場合は、ブラケットの先頭または最後の 文字に指定すればよい。 (つまり `[]-]' は二つの文字 `]' と `-' にマッ チし、 `[--/]' は `-', `.', `/' の 3 文字にマッチする。)

  補集合 (complementation)
`[!...]' と言う表記は、ブラケットの内部に含まれない単一の文字にマッチ する (ただし先頭にある `!' は除外)。 (つまり `[!]a-]' は `]', `a', `-' 以外のすべての文字の、どれか一つにマッチする。 バックスラッシュ `\' を前置すれば、 `?', `*', `[' は通常の文字として 扱われる。またはシェルのコマンドラインの一部に指定する場合は、クォート で囲っても同じ効果が得られる。ブラケットの内部では、これらの文字はその 文字自身だけを意味する。すなわち `[[?*\]' は `[', `?', `*', `\' のど れか一文字にマッチする。

パス名 (pathname)
glob 動作は、パス名のそれぞれの部分に独立に適用される。パス名に存在す る `/' は `?' や `*' ワイルドカードにはマッチしない。また `[.-0]' のよ うな領域指定にもマッチしない。領域指定は、陽に `/' 文字を含むことはで きない。これは文法エラーとなる。 `.' で始まるパス名では、この文字は陽にマッチさせなければならない。 (つ まり `rm *' は .profile を削除しない。また `tar c *' ではすべてのファ イルはアーカイブされない。 `tar c .' の方が良い。)

空のリスト
先に与えた、わかりやすく簡単なルール、「ワイルドカードパターンをマッチ したパス名のリストに展開する」と言うのは、オリジナルの Unix における定 義であった。これはパターンが空のリストに展開されることも許可されていた。 例えば
	xv -wait 0 *.gif *.jpg
において、 *.gif ファイルが全くない場合でも、これは空のリストに展開さ れるため、エラーにならない。 しかし POSIX では、文法的に正しくないパターンや、マッチがなかったパター ンは、そのまま変更されずに残されることになっている。 bash では allow_null_glob_expansion=true を指定することで、以前の振る舞いに設定することができる。 (同様の問題は別のところでも起こっている。例えば、古いスクリプトにおけ る
	rm `find . -name "*~"`
のような記述は、新しいスクリプトでは
	rm -f nosuchfile `find . -name "*~"`
のようにしなければならない。さもないと rm を引き数リストなしで呼び出す可能性があり、エラーメッセージが出てしまう からである。)

注意

  正規表現
ワイルドカードパターンは正規表現と多少似ているが、しかしこの両者は異な る。まず第一に、前者がファイル名にマッチするのに対して、後者はテキスト にマッチする。第二に、ルールも同じではない。例えば正規表現における `*' は、前置された文字の 0 以上の繰り返しを表す。 正規表現にもブラケット表現はあるが、否定は `^' でなされる。 POSIX では ワイルドカードパターンにおける `[^...]' を未定義であるとしている。

  文字クラスと国際化
領域指定は、もともとはもちろん ASCII における順序並びを意味していた。した がって `[ -%]' は `[ !"#$%]' の意味であり、 `[a-z]' は「すべての小文 字」の意味であった。 Unix の実装の中には、これを拡張したものが存在し、 そこでは X-Y という領域指定は、 X のコードと Y のコードに挟まれたコー ドを持つ文字すべてを表すようになっていた。しかし、これにはユーザーがロー カルなシステムにおける文字コードを知らなければならず、さらにローカルな アルファベットに対する照合順序 (collating sequence) が文字コードの順序 と異なっている場合には不便であった。 (訳注: collating sequence に関しては regex(7) を参照して下さい。) したがって POSIX では、ワイルドカードパターンと正規表現の双方において、 ブラケット表記を大幅に拡張して入る。これまで我々は、ブラケット表記には 三つの要素が含まれうることを見てきた。すなわち (i) 否定、 (ii) 単一の 文字、 (iii) 領域指定、の三つである。 POSIX では、領域指定をより国際化 に便利なように定義しており、また三つのタイプをブラケット表記の要素とし て追加している。 (iii) 領域指定 X-Y は X と Y に挟まれた (両端含む) すべての文字を意味 する。このとき、カレントロケール (current locale) の LC_COLLATE カテゴリで定義されている照合順序が用いられる。 (iv) 名前付き文字クラス: 以下のようなものである。
[:alnum:]  [:alpha:]  [:blank:]  [:cntrl:]
[:digit:]  [:graph:]  [:lower:]  [:print:]
[:punct:]  [:space:]  [:upper:]  [:xdigit:]
これを用いれば `[a-z]' の代わりに `[[:lower:]]' のような指定ができる。 またデンマークのように、アルファベットの `z' 以降に 3 つの文字が存在す るような場合でも同じような動作が期待できる。これらの文字クラスはカレン トロケールの LC_CTYPE カテゴリで定義されている。 (v) 照合順序におけるシンボル: `[.ch.]' や `[.a-acute.]' のように `[.' と `.]' で挟まれた文字列は、カレントロケールで定義された照合順序の要素 となる。ある一つの要素が複数の文字からなる場合もありうることに注意。 (vi) 等価クラス表現 (equivalence class expressions): `[=a=]' のように `[=' と `=]' とで挟まれた文字列である。これは等価クラ スのメンバーである照合順序の要素すべてになる。等価クラスはカレントロケー ルで定義されているものになる。例えば `[[=a=]]' は [a\`{a}\'{a}\"{a}\^{a}] (訳注: 日本語の roff ページでは latin1 コー ドが出ないので、ここは TeX で用いる表記をしてあります) と同じ意味にな る。また `[a[.a-acute.][.a-grave.][.a-umlaut.][.a-circumflex.]]' も同じ意味になる。

関連項目
sh(1), glob(3), fnmatch(3), locale(7), regex(7)