コマンドに複数のファイルを一括で指定するときによく使われる、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*
コメント