【bash】シェルにおけるパス名展開「*」「?」
ワイルドカードはよく使いますが、便利なものというのは強力すぎるので正しく扱えるように改めて確認します。
パス名展開
パス名展開は複数ファイルが存在するとき、その中にある一定の規則のファイル名を持つファイル(たとえば、末尾が".txt"の拡張子がついたファイルなど)を一括で引数として実行するときに利用します。
例えば、以下のような要素が詰まったディレクトリがあるとします。
$ ls -a . 001.dat 004.dat 113.dat 333.dat dir1 .. 002.dat 111.dat 114.dat 444.dat dir2 000.dat 003.dat 112.dat 222.dat .dat .txt
ここで dir1とdir2はディレクトリです。
今回はパス名展開で用いられる記号「*」について述べていきます。
「*」
よくワイルドカードと呼ばれています。
「*」は0文字以上の任意文字列に対応し、各ファイル名と照合して任意文字列に対応したパス名を0~9,a~zの順で展開します。
実際に確認します。
$ ls -a . 001.dat 004.dat 113.dat 333.dat dir1 .. 002.dat 111.dat 114.dat 444.dat dir2 000.dat 003.dat 112.dat 222.dat .dat .txt $ ls * 000.dat 002.dat 004.dat 112.dat 114.dat 333.dat 001.dat 003.dat 111.dat 113.dat 222.dat 444.dat dir1: dir2: $ ls .* .dat .txt .: 000.dat 003.dat 112.dat 222.dat dir1 001.dat 004.dat 113.dat 333.dat dir2 002.dat 111.dat 114.dat 444.dat ..:
$ ls -a
最初はディレクトリ内のものをすべてリストしました。
$ ls *
ここで分かるのは「*」のみでは「.」から始まるファイルの展開はできないという事です。
また、dir1/とdir2/は空のディレクトリなので中身はありません。
ちなみに、"ls -R"でほぼ同等(上位互換)の出力が可能です。
$ ls .*
先のことを踏まえ「*」の前に「.」をつけてリストしました。
これにより「.」から始まるファイルの展開ができました。
また、./と../も展開の対象となったため、相対パスのディレクトリの中身もリストしています。
もうすこし細かく使っていきます。
$ ls -a . 001.dat 004.dat 113.dat 333.dat dir1 .. 002.dat 111.dat 114.dat 444.dat dir2 000.dat 003.dat 112.dat 222.dat .dat .txt $ ls *.dat 000.dat 002.dat 004.dat 112.dat 114.dat 333.dat 001.dat 003.dat 111.dat 113.dat 222.dat 444.dat $ ls 0*.dat 000.dat 001.dat 002.dat 003.dat 004.dat $ ls *1*.dat 001.dat 111.dat 112.dat 113.dat 114.dat
$ ls -a
省略
$ ls *.dat
ファイル名に「.dat」を含むファイルが展開・リストされます。
$ ls 00*.dat
頭に「0」、末尾に「.dat」が付くファイルが展開・リストされます。
「*」は0文字以上の任意文字列なので、"01, 02, 03, 04"が対応しています。
$ ls *1*.dat
「*」は複数同時に利用することも可能です。
最後はディレクトリを超えて使ってみます。
$ ls -R .: 000.dat 003.dat 112.dat 222.dat dir1 001.dat 004.dat 113.dat 333.dat dir2 002.dat 111.dat 114.dat 444.dat ./dir1: ./dir2: $ mv 1*.dat dir1/ $ mv 2*.dat dir2/ $ ls -R.dat .: 000.dat 002.dat 004.dat 444.dat dir2 001.dat 003.dat 333.dat dir1 ./dir1: 111.dat 112.dat 113.dat 114.dat ./dir2: 222.dat $ ls */*2.dat dir1/112.dat dir2/222.dat
$ ls -R
ディレクトリの内容までリストしています。
$ mv 1*.dat dir1/
$ mv 1*.dat dir1/
「*」を用いてファイルの移動を行いました。
$ ls -R
各ファイルの位置を確認してます。
$ ls */*2.dat
ディレクトリの情報も含めてパス名展開しました。
「?」
「*」と合わせてワイルドカードと呼ばれます。
「?」は1文字の任意文字に対応し、各ファイル名と照合して任意文字に対応したパス名を0~9,a~zの順で展開します。
- 「*」: 0文字以上の任意文字列
- 「?」: 1文字の任意文字
「?」の方が制限が強めなことがわかります。
一応軽く利用してみます。
$ ls -a . 001.dat 004.dat 113.dat 333.dat dir1 .. 002.dat 111.dat 114.dat 444.dat dir2 000.dat 003.dat 112.dat 222.dat .dat .txt $ ls ?1?.dat 111.dat 112.dat 113.dat 114.dat
「*」で十分確認できたはずなので、解説については省略します。
おわりに
パス名展開「*」「?」については以上です。
残りのパス名展開については別の記事で。
要らないファイルを一気に削除したりと便利ではあるのですが、
$ rm *.dat
として大事なデータもなくすリスクもあります。
このリスクを回避するため、rm
に関する記事もそのうち書きたいです。