概要
ファイルパスを指定する際によく使用される glob パターンについて解説します。 glob パターンは以下のような場面で日常的に利用されています:
- シェルでのファイル名の展開
- Python の
globモジュールによるファイル検索 .gitignoreでのファイル除外設定- ビルドツールでの対象ファイルの指定
glob
glob は、ワイルドカード を利用したファイルパスを指定する構文です。
任意の 1 文字 ? ([] で囲われていないもの)
? は任意の 1 文字にマッチします。
例: hoge? の場合、hoge1, hoge2 にマッチします。
任意の文字列 * ([] で囲われていないもの)
* は空の文字列を含む任意の文字列にマッチします。
例: hoge* の場合、hoge, hoge123 にマッチします。
いずれかの 1 文字 [<文字>]
[] の中のいずれか 1 文字にマッチします。
例: [abc]def の場合、adef, bdef, cdef にマッチします。
[]の中の文字は[]*?などであってもそのままの文字として扱われます。
例:[[*?]の場合、[、*、?のいずれか 1 文字を表します。-で区切られた 2 つの文字は、範囲を表します。
例:[A-Z]: 大文字のアルファベットのいずれか 1 文字
例:[a-z]: 小文字のアルファベットのいずれか 1 文字
例:[a-zA-Z]: アルファベットのいずれか 1 文字
例:[0-9]: 数字のいずれか 1 文字!は否定を表し、そのあとに続く文字以外を表します。 例:[!abc]:a、b、c以外のいずれか 1 文字を表します。
エスケープ
特殊文字 (?、*、[、]) をそのままの文字として扱いたい場合は、文字の前に \ を付けてエスケープします。
ただし、使用する環境 (シェルやプログラミング言語) によって、エスケープの方法が異なる場合があるので注意が必要です。
例:
\*.txt→ ファイル名が*.txtであるファイルにマッチtest\?→ ファイル名がtest?であるファイルにマッチ
補足: シェルでは、\ によるエスケープの代わりにシングルクォートを使用することもできます。
ls '[2021]*' # ファイル名が[2021]で始まるファイルを表示
パス名
glob パターンでパスを指定した場合、セパレータで区切られた部分ごとにマッチングが行われます。
例: [abc]hoge/*.jpg のようにパスを指定した場合、「[abc]hoge にマッチするディレクトリ以下にある *.jpg にマッチするファイル」と解釈されます。
任意の階層 **
hoge
├── depth1
│ ├── depth2
│ │ └── untitled.txt
│ └── untitled.txt
└── untitled.txt
このような階層になっていた場合、
hoge/*/*.txt の場合、hoge の 1 階層下にあるディレクトリ内にある *.txt にマッチするファイルという意味になります。
hoge/depth1/untitled.txt
hoge/depth2/untitled.txt
これを hoge/**/*.txt とすると、hoge 以下の任意の階層にある *.txt にマッチするファイルという意味になります。
hoge/untitled.txt
hoge/depth1/untitled.txt
hoge/depth1/depth2/untitled.txt
hoge/depth2/untitled.txt
この方法は指定ディレクトリ以下をすべて検索するので、階層構造が深くなっている場合は処理に時間がかかるため、注意してください。
利用例
Python の glob
pathlib の Path.glob() を使用した実践的な例を示します:
from pathlib import Path
for path in Path().glob("hoge/**/*.txt"):
print(path)
hoge/untitled.txt hoge/depth2/untitled.txt hoge/depth1/untitled.txt hoge/depth1/depth2/untitled.txt

コメント