Bashによるパス名の展開まとめ

2017年10月27日

コマンドに複数のファイルを一括で指定するときによく使われる、Bashによるパス名の展開についてまとめました。

パス名展開

Bashは、コマンドの引数に「*」「?」「[」が含まれていると「パターン」とみなします。パターンにマッチするファイルがあれば、そのファイル名に置き換えられます。複数のファイルに一致する場合は、それらのファイル名を並べたリストに置換されます。マッチするファイルがなければ、通常は置き換えずにコマンドに渡されます。

パス名展開のルール

*(アスタリスク)
長さ0以上の文字列にマッチします。
?(疑問符)

任意の一文字にマッチします。
[文字](角括弧で括られた文字)
括られた文字のうちいずれかにマッチします。[a-z](アルファベットの小文字aからzまでの文字)のように範囲で指定することもできます。

[^文字] もしくは [!文字]
括られた文字以外の文字のいずれかにマッチします。[^0-9](数字以外の文字)のように範囲で指定することもできます。

なお、「'」(シングルクォーテーション)や「"」(ダブルクォーテーション)で括られた文字列はパターンマッチからは除外され、そのままコマンドに渡されます。

チルダ展開

パス名展開と組み合わせてよく使われるのがチルダ展開です。以下のルールで置換されます。この置換は、パス名展開より前に行われます。パス名展開と違い、ファイルの有無に関わらず展開されます。

~
ホームディレクトリに置換
~ユーザ名
指定したユーザ名のホームディレクトリに置換

ブレース展開

パス名展開は、ブレース展開と組み合わせて使うこともできます。ブレース展開の動作は、例を見たほうが早く理解できるでしょう。以下は実行例です。

$ echo 123{ABC,DEF,GHI}456
123ABC456 123DEF456 123GHI456

ブレース({})で括られた「ABC」「DEF」「GHI」それぞれに、前に書かれた「123」、後ろに書かれた「456」を追加して展開する、という動作になります。前後の文字列がなければ追加されません。
ブレース展開も、パス名展開より前に行われ、ファイルの有無に関わらず展開されます。

パス展開と組み合わせて使われることが多い「..」と「.

パス名に使うことができる「..」(ピリオド2つ)と「.」(ピリオド1つ)はパス展開ではありませんが、パス展開と組み合わせて使うことがよくあります。あわせて覚えておくといいでしょう。

..
親ディレクトリ
.
カレントディレクトリ

以下のように実行すると、「カレントディレクトリの2つ上のディレクトリにあるsample.txtを出力する」という意味になります。

cat ../../sample.txt

パス展開の例

# カレントディレクトリにあるファイルを一覧表示(ドットファイルを除く)
ls -ld *

# カレントディレクトリにあるドットファイルを一覧表示(「.」と「..」を含む)
ls -ld .*

# カレントディレクトリにあるドットファイルを一覧表示(「.」と「..」を除外)
ls -ld .[^.]*

# カレントディレクトリにあるドットファイルを /some/where にコピー(「.」と「..」を除外)
cp -ar .[^.]* /some/where

# ホームディレクトリにある拡張子が2文字のファイルを一覧表示
ls -ld ~/*.??

# ホームディレクトリにある「File」または「file」をファイル名に含むファイルを一覧表示
ls -ld ~/*[Ff]ile*

# /etcにある小文字アルファベットで始まらないファイルを一覧表示
ls -ld /etc/[^a-z]*

# ユーザー「lintaro」のホームディレクトリにある拡張子が「txt」のファイルを一覧表示
ls -ld ~lintaro/*.txt

# /usr/bin/ または /usr/sbin にある a で始まるファイルを一覧表示
ls -ld /usr/{bin,sbin}/a*