連載
» 2017年08月29日 05時00分 公開

Dev Basics/Keyword:glob(グロブ)

globパターンを利用すると、「*」「?」「[]」などのワイルドカードや文字クラスを組み合わせて、多数のファイルパスをまとめて表記できる。

[かわさきしんじ,Insider.NET編集部]
「Dev Basics/Keyword」のインデックス

連載目次

 「glob」とは「*」「?」などのワイルドカードを使ったファイルパス(globパターン)から、それにマッチする実際のファイルパスを展開すること。

UNIXのglob

 本はといえば、globはUNIXの初期バージョンに搭載され(/etc/globコマンド)、ファイル名展開を行うために使われていた。/etc/globが提供していた機能は後に、globライブラリ関数として提供されるようになり、各種のシェルで使われるようになった。

 UNIXのglobでは以下のワイルドカードパターンや文字クラスを使用できる。

  • *: 0文字以上任意の文字列にマッチする
  • ?: 任意の1文字にマッチする
  • []: []に含まれる文字のいずれか1文字にマッチする

 []を利用した表記のことを「文字クラス」と呼ぶ。文字クラスでは、[abcdefg]のような記述と、[a-g]のような記述が可能である。後者はハイフン(-)を使い[abcdefg]と同じ範囲を表現している。つまり、両者は「abcdefgのいずれか1文字にマッチ」することになる。また、このときには「!」を使って範囲を反転することもできる。例えば、[!abc]は「abc以外のいずれか1文字にマッチ」する。

 例として、macOSでのglobの利用例を以下に示す(タブ位置は適宜調整してある。以下、同様)。

$ ls …… 全てのファイルを一覧
abc.txt  bbc.txt  boo.txt  foo.txt  gooo.txt
$ ls ?bc* …… 先頭が任意の文字、その後に「bc」が続くもの
abc.txt  bbc.txt
$ ls *oo.txt …… 最後が「oo」で拡張子が「.txt」になっているもの
boo.txt  foo.txt  gooo.txt
$ ls ?oo.txt …… 先頭が任意の文字、その後に「oo」が続く、拡張子が「.txt」のファイル
boo.txt  foo.txt
$ ls [a-c]* …… ファイル名が「abc」のいずれかで始まるもの
abc.txt  bbc.txt  boo.txt
$ ls [!a]bc* …… ファイル名が「a」以外で始まり、次に「bc」が続くもの
bbc.txt


macOS(ターミナル)でのglobパターンの使用例

 「*oo.txt」と「?oo.txt」の違いは、前者では「oo」の前は任意の長さの文字列がマッチするため、「gooo」もマッチするのに対して、後者では「oo」の前には任意の1文字のみがマッチするため、「gooo」はマッチしない点にある。

 また、Windows(MS-DOS)のコマンドプロンプトでは、上記のうち、ワイルドカード(*と?)のみが使用できる。以下に例を示す(表示を簡潔にするために/bオプションを指定している)。文字クラス([])を使用できない点に注目しよう。

> dir /b …… 全てのファイルを一覧
abc.txt
bbc.txt
boo.txt
foo.txt
gooo.txt

> dir /b ?bc* …… 先頭が任意の文字、その後に「bc」が続くもの
abc.txt
bbc.txt

> dir /b *oo.txt …… 最後が「oo」で拡張子が「.txt」になっているもの
boo.txt
foo.txt
gooo.txt

> dir /b ?oo.txt …… 先頭が任意の文字、その後に「oo」が続く、拡張子が「.txt」のファイル
boo.txt
foo.txt

> dir /b [abc]*.txt …… []は使えない
ファイルが見つかりません


コマンドプロンプトでのワイルドカードの使用例

 PowerShellでは[]を使用できる。ただし、「[!a]*」のように、文字クラスで指定した範囲を反転することはできない。以下に例を示す(空行は筆者が適宜削除している)。

> ls ?bc* …… 先頭が任意の文字その後にbcが続くもの

    ディレクトリ: C:\project\devbasics\glob

Mode                LastWriteTime         Length Name
----                -------------         ------ ----
-a----       2017/08/28     10:27              0 abc.txt
-a----       2017/08/28     10:27              0 bbc.txt

> ls [abc]*.txt …… PowerShellでは[]が使える

    ディレクトリ: C:\project\devbasics\glob

Mode                LastWriteTime         Length Name
----                -------------         ------ ----
-a----       2017/08/28     10:27              0 abc.txt
-a----       2017/08/28     10:27              0 bbc.txt
-a----       2017/08/28     10:27              0 boo.txt

> ls [!a]bc.txt …… ただし[!……]は使えない

    ディレクトリ: C:\project\devbasics\glob

Mode                LastWriteTime         Length Name
----                -------------         ------ ----
-a----       2017/08/28     10:27              0 abc.txt

PowerShellでのglobパターンの使用例

globパターンの拡張

 ここまでに見てきたのはある意味では「古典的」なglobパターンとなる。最近では、.gitignoreファイルやVisual Studio Codeのsettings.jsonファイルなどで、上で見たglobパターンよりも柔軟な形でファイルパスを記述できるようになってきている。典型的なのが「**」を使ったものだ。これはいわゆる「globstar」と呼ばれるもので、ファイルパス中にこれが現れると「0個以上のディレクトリ/サブディレクトリ」にマッチするようになる。単独で使用した場合には、カレントディレクトリ以下の全てのファイル/ディレクトリにマッチする。

 例えば、Visual Studio Codeの設定では[エクスプローラー]ビューに表示する/表示しないファイルの切り替えは次のようにして指定している(デフォルト値)。

"files.exclude": {
  "**/.git": true,
  "**/.svn": true,
  "**/.hg": true,
  "**/CVS": true,
  "**/.DS_Store": true
},


Visual Studio Codeでのglobstarの使用例

 これはプロジェクトのトップレベルのディレクトリ以下にある全ディレクトリのうち、「.git」「.svn」「.hg」「.CVS」「.DS_Store」にマッチするものを意味する。そして、マッチしたファイル/ディレクトリは[エクスプローラー]ビューに表示されない。

 ちなみにglobstarはBashなどのシェルでglobstarオプションを設定することで(shopt -s globstar)、シェルからでもglobstar表記を利用できるようになる。例えば、「ls **」などを実行すると、「カレントディレクトリ以下の全てのファイル、ディレクトリを全て一覧」してくれる。以下は、macOSにglobstarオプションを利用可能なBashをインストールして、「ls *」コマンドと「ls **」コマンドを実行したものだ。

$ ls * …… 「*」はカレントディレクトリ直下のファイルとディレクトリにマッチ
abc.txt  bbc.txt  boo.txt  foo.txt  gooo.txt

tmp:
bar.txt  tmp2
$ ls ** …… 「**」はカレントディレクトリ以下の全ファイル/ディレクトリにマッチ
abc.txt    foo.txt      tmp/tmp2/baz.txt
bbc.txt    gooo.txt
boo.txt    tmp/bar.txt

tmp:
bar.txt  tmp2

tmp/tmp2:
baz.txt


Bashで「ls *」コマンドと「ls **」コマンドを実行したところ

 「ls *」コマンドでは、シェルが「*」を「5つのファイルとtmpディレクトリ」に展開してからlsコマンドに渡すので、それらが表示されるだけとなる。一方、「ls **」コマンドでは、「**」がカレントディレクトリ以下の全てのファイル/ディレクトリにマッチするので、上記の「5つのファイルとtmpディレクトリ」だけではなく、「tmpディレクトリにあるbar.txtファイルとtmp2ディレクトリ、tmp2ディレクトリにあるbaz.txtファイル」にもマッチしていることが分かる(ファイルの一覧に7つのファイルが表示され、tmp/tmp2ディレクトリの内容も表示されている点に注目)。

 この他にも、Bashなどのシェルで採用されている「Extended Globbing」機能を利用できる場合もある(Bashで利用するには「shopt -s extglob」コマンドを実行する)。例えば、Node.jsで利用可能なnode-globパッケージではExtended Globbing機能が提供する以下のglobパターンを利用できる。

  • !(pattern-list): pattern-listに記述したものにマッチしないものを意味する
  • ?(pattern-list): pattern-listに記述したもの(0回か1回)
  • *(pattern-list): pattern-listに記述したもの(0回以上)
  • +(pattern-list): pattern-listに記述したもの(1回以上)
  • @(pattern-list): pattern-listに記述したもののいずれかに1回だけマッチ

 pattern-listには、これまでに見てきたようなパターンを記述できる。以下にnode-globパッケージの使用例を示す。

var glob = require("glob");

glob("?bc*", function(err, files) {
  console.log("?bc*");
  for (var item of files) {
    console.log(item);
  }
});

glob("!(abc)*.txt", function(err, files) {
  console.log("!(abc)*");
  for (var item of files) {
    console.log(item);
  }
});

glob("*([ab])bc*", function(err, files) {
  console.log("*([ab])bc*");
  for (var item of files) {
    console.log(item);
  }
});

glob("@(abc|bbc|foo).txt", function(err, files) {
  console.log("@(abc|bbc|foo).txt");
  for (var item of files) {
    console.log(item);
  }
});

node-globパッケージの使用例

 glob関数では第1引数にglobパターンを指定し、コールバック関数でそのパターンにマッチしたファイル群を受け取り、そのファイル名を表示しているだけだ。このスクリプトの実行例を以下に示す。

$ ls *.txt
abc.txt  bc.txt   foo.txt
bbc.txt  boo.txt  gooo.txt
$ node hoge.js
?bc* …… 「?bc*」はabc.txt、bbc.txtにマッチする
abc.txt
bbc.txt
!(abc)*.txt …… 「!(abc)*」はabc.txt以外の全ての.txtファイルにマッチする
bbc.txt
bc.txt
boo.txt
foo.txt
gooo.txt
*([ab])bc* …… 「*([ab])bc*」はabc.txt、bbc.txt、bc.txtにマッチする
abc.txt
bbc.txt
bc.txt
@(abc|bbc|foo).txt …… 「@(abc|bbc|foo).txt」は以下の3つにマッチする
abc.txt
bbc.txt
foo.txt


実行例

 また、このパッケージでは「{a, b}bc.txt」のような記述も可能だ。これは{}内にカンマ区切りで記述した要素が、それぞれ他の部分と連結される。従って、今示したパターンは「abc.txt」と「bbc.txt」に展開される。


 globパターンを利用すると、「*」「?」「[]」などのワイルドカードや文字クラスを組み合わせて、多数のファイルパスをまとめて表記できる。最初のうちは、使いこなしが難しいかもしれないが、簡単なパターンから始めて、徐々にその意味するところを体得していけば、最終的にはExtended Globbingで提供される拡張パターンマッチ機能なども使いこなせるようになるだろう。

参考資料

  • GLOB(7): globのmanページ
  • Pattern Matching: Bashマニュアルでのパターンマッチングの解説。Extended Globbingの説明がある
  • node-glob: node-globパッケージのリポジトリ。globの簡単な説明もある

「Dev Basics/Keyword」のインデックス

Dev Basics/Keyword

Copyright© 1999-2017 Digital Advantage Corp. All Rights Reserved.

@IT Special

- PR -

TechTargetジャパン

この記事に関連するホワイトペーパー

RSSについて

アイティメディアIDについて

メールマガジン登録

@ITのメールマガジンは、 もちろん、すべて無料です。ぜひメールマガジンをご購読ください。