重要: ワイルドカードの展開はシェルが行います。多くの破壊的コマンド(例: rm)でワイルドカードを使うと取り返しがつかない操作になるため注意してください。
クイックリンク
- ワイルドカードとは
- 1文字を指定する: “?”
- 複数文字を一致させる: “*”
- 角括弧で範囲を指定する
- 丸括弧で代替を指定する
- “!” と “^” で除外する
- クォートでワイルドカードを無効にする
ワイルドカードとは
ワイルドカード(メタ文字とも呼ぶ)は、他の文字の集合やパターンを表す記号です。カードゲームのジョーカーのように、ある条件を満たす任意の文字や文字列を表現できます。
目的: ファイル名一覧(パターンに合うファイル群)をシェルに生成させ、他のコマンドへ渡すことです。例えば多数のファイルを対象に操作する際、すべてのファイル名を手で書く必要はありません。シェルにパターンを渡すと、シェルが一致するファイル名のリストに展開してからコマンドに渡します。プログラム側はワイルドカードを受け取りません。
注意点: ワイルドカードの挙動はシェルによって多少異なります。多くの基本機能は Bash と zsh で共通していますが、zsh は拡張グロブ(高度なマッチ)を豊富に持つため、上級者に人気があります。
用語の一行定義:
- グロブ: シェルが行うワイルドカードによるパターン展開のこと。
1文字を指定する: “?”
“?” は、ファイル名の任意の1文字に一致します。ちょうど1文字だけを置き換えたいときに使います。
例: JPEG ファイルで名前が photo_01, photo_02 のような場合、以下のように指定できます。
ls photo.0?.jpg
この例では “photo.01.jpg” などが一致します。
代替挙動: パターンに一致するファイルがない場合、シェルの設定によってはパターンそのものが残るか、空リストになるか、エラーになるかが変わります(後述)。
重要: 日本語やマルチバイト文字を含むファイル名は、シェルが UTF-8 環境で正しく扱う必要があります。ロケールが不適切だと意図した一致が行われません。
複数文字を一致させる: “*”
“*”(アスタリスク)は 0 個以上の任意の文字列に一致します。最も頻繁に使うワイルドカードです。
例: カレントディレクトリの全ての JPEG ファイルを表示する:
ls *.jpg
ディレクトリ以下に限定する場合:
ls photos/*.jpg
複合例: 末尾の拡張子が “.pl” または “.py” のスクリプトを表示する:
ls *.p?
文字列の途中にパターンを置くこともできます:
ls *d*
zsh では再帰的にサブディレクトリも検索する “” を使えます。
ls ~/
ls /usr/**/bin
補足: “*“(アスタリスク三重)はシンボリックリンクも含めて検索する動作をするシェルがある点に注意してください(シェル依存)。
Windows の “.“ は MS-DOS の慣習ですが、Linux では “*” だけで十分です。
コピーの例:
cp * /other/directory
警告: rm や mv のような破壊的コマンドでワイルドカードを使うときは細心の注意を払ってください。必ずバックアップや確認オプション(例: rm -i)を検討してください。
角括弧で範囲を指定する
角括弧 [ ] の中に文字や範囲を列挙すると、そのいずれか1文字に一致します。
単純な列挙:
[abc]
範囲指定:
[a-z]
[A-Z]
[0-9]
[a-zA-Z0-9]
角括弧は他のワイルドカードと組み合わせて使うのが一般的です。例えば、.pl と .py を同時にマッチさせるなら:
ls *.p[ly]
この例は「.p のあとに l または y が続くファイル」を一致させます。
また、角括弧の先頭に範囲否定を付けることができます(次節で説明)。
波括弧で並列・連続を作る
Bash や zsh では波括弧 { } を使った展開(Brace expansion)があります。これはワイルドカードではなく、シェルの展開機能です。
複数の単語を列挙:
echo {cat,dog}
連続した範囲を生成:
echo {a..d}
echo {1..10}
波括弧展開はコマンドライン上で複数の文字列を簡単に作るのに便利です。ただし、ファイル名が存在しない場合に ls などを使うとエラーになることがあります。
丸括弧で代替を指定する
拡張グロブ(extglob)を有効にすると、丸括弧と “|” を使ってオル(or)条件を表現できます。Bash では shopt -s extglob、zsh では setopt EXTENDED_GLOB を使います。
例: .pl または .py をマッチさせる方法(extglob が有効な場合):
ls *.(pl|py)
括弧内での代替:
.*p(l|y)
拡張パターンの例:
- +(pattern): 1 回以上の繰り返し
- *(pattern): 0 回以上の繰り返し
- ?(pattern): 0 回または1回
- @(pattern): ちょうど1回
- !(pattern): 指定パターン以外
これらは複雑な条件を短く書くのに便利です。例えば、拡張を使って拡張子が .jpg/.png/.gif のいずれかを一括で表現できます。
ls *.@(jpg|png|gif)
除外する: “!” と “^”
角括弧の先頭に “!” または “^” を置くと、その文字クラスに含まれない文字に一致します。
例: 小文字 a-z を含まないファイル名の1文字目を探す:
ls [!a-z]
また、拡張グロブの “!(pattern)” を使えば、丸括弧内のどれにもマッチしない名前を選べます。
ls !(a|b|c)
シェルや設定によっては否定の扱いが微妙に異なるので、複雑なパターンを使う前に echo や ls で展開結果を確認する習慣をつけましょう。
ワイルドカードを無効にする: クォート
コマンドに文字列をそのまま渡したいときはクォート(引用)でワイルドカードの展開を抑止します。正規表現や一部の特殊文字をそのまま使いたい場合に重要です。
- シングルクォート: すべての展開を抑止(変数展開も含む)
grep '^foo'
- ダブルクォート: 変数展開は有効だがワイルドカードは抑止
grep "^$expression"
注意: クォートの使い方を誤ると、意図した変数展開やパターン展開が動作しないことがあります。
シェル設定で挙動が変わる(Bash と zsh の例)
Bash の代表的なオプション:
- nullglob: パターンに一致しないと空リストにする(デフォルトはパターンを残す)
- failglob: パターンに一致しないとエラーにする
- dotglob: ドットで始まるファイル名(隠しファイル)も “*” でマッチする
- extglob: 拡張グロブを有効にする
Enable 例:
shopt -s nullglob
shopt -s extglob
shopt -s dotglob
zsh はさらに多様なグロブ修飾子を持ちます。例えば **/*(.m)
のようにファイルタイプでフィルタリングできるなど強力です。
実務ヒント: スクリプトを書くときはシェルのオプションを明示的に設定・記載しておくと、異なる環境での再現性が向上します。
よくある落とし穴と回避策
- ドットファイルの見落とし
- 問題: “*” は通常ドットで始まるファイルをマッチしません。
- 回避: dotglob を使うか、明示的に “.” を含める。
- 大量ファイルでのコマンド引数リストの上限(ARG_MAX)
- 問題: 一度に展開されるファイル数が非常に多いと、コマンドライン長の制限に達する。
- 回避: find と -exec や xargs を使ってバッチ処理する。
例:
find . -name "*.jpg" -print0 | xargs -0 ls -l
- 破壊的コマンドでの誤指定
- 問題: rm * を想定外のディレクトリで実行すると大量削除になる。
- 回避: rm -i を使う、あるいはゴミ箱ツールを使う。
- 期待と異なるエスケープ
- 問題: シェルでのクォートを忘れて正規表現やメタ文字が展開される。
- 回避: 単一引用符やダブル引用符を正しく使う。テストには echo を使う。
代替アプローチ
- find コマンド: 複雑な条件(更新時間、サイズ、所有者)でファイルを絞り込む場合に有利
- rg / grep: 内容で検索してファイル名を得たい場合
- ファイルマネージャや GUI: 視覚的に確認しながら操作したい場合
どれを使うかは目的と対象の規模によります。速さと柔軟性を重視するなら find + xargs、単純なファイル名だけならシェルグロブで十分です。
実務向けチェックリスト
初心者向け
- echo パターン で展開結果を確認する
- rm を使うときは -i をつける
- スペースを含むファイル名に注意する(クォートが必要)
開発者・スクリプト作成者向け
- スクリプトの先頭で shopt 設定を明示する
- 大量ファイルは find + -exec/xargs に切り替える
- テスト環境で想定されるファイル名(特殊文字含む)を用意して検証する
システム管理者向け
- バックアップとロールバック手順を用意する
- cron ジョブでワイルドカードを使う時はログとエラーハンドリングを実装する
事故発生時の簡易ランブック(ワイルドカードで誤って削除した場合)
- 操作を直ちに停止する(追加の rm 等をやめる)。
- すぐにファイルシステムの状態を確認する(ls, stat)。
- 可能ならアンマウントして複製イメージを作る(安全な調査のため)。
- バックアップから復旧するか、削除直後なら extundelete / testdisk のようなツールで回復を試みる(ファイルシステムに依存)。
- 復旧不可能な場合、教訓をドキュメント化して再発防止策を導入する(rm の代わりに安全なスクリプトを使う等)。
重要: 上書きや削除の直後は、ディスクへの書き込みを行わないこと。上書きすると復旧確率が下がります。
メンタルモデルとヒューリスティック(考え方)
- ワイルドカードは “シェルへの問い合わせ”: シェルに対して “こういうファイルをください” と言っている。
- まずは一覧を確認する: echo や ls で展開をチェック。
- 破壊的操作は常に二段階で行う: 1) 対象を確認、2) 実行(確認済み)。
- 大量処理にはパイプライン(find、xargs)を使う。
互換性と移行のヒント
- Bash スクリプトを zsh に移す場合、extglob の扱いや dotglob のデフォルトが異なる点に注意。
- POSIX シェル (/bin/sh) は拡張グロブをサポートしないことが多い。移植性を重視するなら基本的な “*” と “?”、角括弧のみを使う。
- スクリプトの冒頭にシェバン(#!/bin/bash など)を明記しておくと、実行環境の差を吸収しやすい。
テストケース例(受け入れ条件)
- ファイル群: a.txt, b.txt, .hidden, image.jpg, photo.01.jpg
- パターン: *.jpg -> 期待: image.jpg, photo.01.jpg
- パターン: photo.0?.jpg -> 期待: photo.01.jpg
- パターン: [ab].txt -> 期待: a.txt, b.txt
- パターン: .* -> 期待: .hidden(ただし dotglob が無効なら一致しない)
スクリプトは上記を満たすように、echo で実際の展開を検証してから処理すること。
参考コマンド集(チートシート)
- 展開を確認: echo PATTERN
- Bash で extglob 有効化: shopt -s extglob
- Bash で nullglob 有効化: shopt -s nullglob
- dot ファイルを含める: shopt -s dotglob
- find と組み合わせる: find . -name “*.jpg” -print0 | xargs -0 command
決定木: いつワイルドカードを使うべきか
以下の簡易フローチャートで判断できます。
flowchart TD
A[ファイル名だけで選べるか?] -->|はい| B[単純なワイルドカード(*、?、[])で十分]
A -->|いいえ| C[内容や属性で選ぶ必要がある]
C --> D[find を使う]
B --> E[ワイルドカードで一覧を確認(echo/ls)]
E --> F{削除や移動など破壊的操作か?}
F -->|はい| G[確認オプションを付けるかテスト実行]
F -->|いいえ| H[そのまま実行]
G --> I[必要ならバックアップ]
1行用語集
- グロブ: シェルによるワイルドカード展開のこと。
- extglob: Bash の拡張グロブ機能。複雑なパターンが使える。
- nullglob: 一致なしで空リストを返すオプション。
- dotglob: “.” で始まるファイル名をワイルドカードで含めるオプション。
まとめ
ワイルドカードは日常のファイル操作を圧倒的に効率化します。基本は “?” と “*”、角括弧での文字クラスです。拡張が必要なら extglob を有効にして丸括弧や否定パターンを使いましょう。実務では、まず展開結果を確認し、破壊的操作は二段階で行い、find や xargs を使って大量ファイル処理に耐える設計にすることが重要です。
要点:
- まず echo で展開を確認する習慣をつける
- 破壊的コマンドは慎重に実行する
- スクリプトではシェルオプションを明示する
重要: ワイルドカードの挙動はシェルとその設定に依存します。移植性や安全性を意識して使い分けてください。
要約と行動案: 上記のチェックリストを参照して、自分のワークフローに必要なオプション(extglob, nullglob, dotglob)を選び、テストケースを作ってから本番で適用してください。