シェルスクリプト

シェルのワイルドカードの使い方

投稿日:

シェルでファイル名を指定するとき、ワイルドカードを使うことができます。

コマンドラインでワイルドカード文字を含むファイル名は、それにマッチするすべてのファイルに展開されるので、特定の文字列を含む複数のファイルを指定したりするのがとても簡単になります。

例えば次のように指定すると(*がワイルドカード文字)「.txt」で終わるファイルすべてを一覧できます。

$ ls *.txt

ワイルドカードは大変便利ですが、ファイルを操作するコマンド(特に削除コマンド)での使用には細心の注意が必要です。

中でも単独の「*」の使用は十分に注意する必要があります。意図しないファイル名が含まれないようにすることはもちろん、うっかりミスで大事故につながることもあります。これについては後述します。

ワイルドカードの種類

シェルで利用できるワイルドカードの種類には次のようなものがあります。

ワイルドカード意味
*0個以上の任意の文字列
?1文字
[...][ ]の中の任意の1文字
[!...][ ]に中の任意の文字以外の1文字

コマンドラインにこれらのワイルドカード文字があれば、シェルはマッチするファイル名に展開してからコマンドを実行します。

どのように展開されるかは「set -x」でトレース情報の表示を有効化した後、echoコマンドを実行して確認できます。

例えばa.txt、b.txt、c.txtというファイルのあるディレクトリで次のようにコマンドを実行してみてください。

$ set -x
+ set -x
...
$ echo *.txt
+ echo a.txt b.txt c.txt
a.txt b.txt c.txt
...

「*」は0個以上の任意の文字列を表すので「*.txt」はa.txt、b.txt、c.txtのいずれにもマッチします。したがって「*.txt」は「a.txt」「b.txt」「c.txt」に展開されてechoコマンドに渡されます。

+ echo a.txt b.txt c.txt

この後はそれぞれのワイルドカードの指定方法の例をいくつか紹介します。

*を使う例

「*」は0個以上の任意の文字列を表します。以下にいくつか指定方法の例を挙げます。

*foo           # fooで終わるファイル。fooというファイルがあればそれも含む
foo*	       # fooで始まるファイル。fooというファイルがあればそれも含む
*foo*	       # fooを含むファイル。fooで始まるものやfooで終わるものも含む
a*c            # aで始まりcで終わるファイル
 *             # カレントディレクトリのすべてのファイル(ただし隠しファイルは除く)
bar/*	       # barというディレクトリ下の全ファイル(ただし隠しファイルは除く)

?を使う例

「?」は任意の1文字を表します。以下にいくつか指定方法の例を挙げます。

??	       # 名前が2文字のファイル
foo??          # fooの後に2文字が続くファイル
??*	       # 名前が2文字以上のファイル

[...]や[!...]を使う例

[...]は[と]で囲まれた文字列のうちの1文字を表します。[の直後に!を続けると否定の意味になります。つまり[と]で囲まれた文字列のうちの文字以外の1文字を表します。

[ab][xyz]      # 1文字がa、bのいずれか、2文字目がx、y、zのいずれかのファイル
[ab][xyz]??    # 最初の2文字は上の例と同じだがその後に任意の2文字が続く

[...]や[!...]では「-(ハイフン)」を使って範囲を指定することもできます。

[a-z]*	       # アルファベットの小文字で始まるファイル
[-a-z]*	       # -(ハイフン)か、アルファベットの小文字で始まるファイル
[a-zA-Z]       # アルファベットの小文字か大文字で始まるファイル
*[0-9][0-9]    # 2桁の数字で終わるファイル
[!0-9]*	       # 数字では始まらないファイル

ただし国際化対応などでUnicodeなどのASCII以外の文字セットが使われるようになると文字の範囲は単純ではなくなってきています。

範囲指定を使う場合は、上記のようにアルファベットの小文字、大文字、数字の範囲に限った方が良いでしょう。

隠しファイル

「.」で始まるファイル名は「隠しファイル」と呼ばれます。これは単にlsコマンドを実行しただけでは通常は表示されないためそのように呼ばれます。

ワイルドカードを使うときも隠しファイルは例外です。隠しファイルにマッチさせたい場合は、最初の文字が.であると明示的に指定する必要があります。

そのため前述したワイルドカードの指定例はすべて隠しファイルにはマッチしません。

以下にいくつか例を示します。

.*	       # 隠しファイルすべて。ただし.や..も含まれる
.bash*	       # .bashで始まるファイル
bar/.*	       # barディレクトリの隠しファイルすべて

ただし、次のように指定しても隠しファイルは含まれませんので注意してください。

[.b]*	       # bで始まるファイル。.で始まるファイルは含まれない

また次のように指定して、隠しファイルと通常のファイルすべてを指定するのも間違いです。

.?*            # 隠しファイル全てと同じ。通常のファイルは含まれない

ファイルを操作するコマンドでは十分に注意しよう

ワイルドカードは大変便利ですがファイルを操作するコマンド、特に削除コマンドを実行するときには十分注意しましょう。

例えば最も恐ろしいのは次のような間違いです。

rm -rf *
rm -rf /*

カレントディレクトリの中のファイルやディレクトリをすべて削除するつもりが、うっかり2番目のようにタイプしてしまったときです。これを実行したことはありませんが、これはうっかりでは済まされない大惨事です。

ここまではないにしても次のようなミスもあるでしょう。

rm tmp/*
rm /tmp/*

カレントディレクトリの下のtmpディレクトリの中のファイルを消そうとして、2番目のようにタイプしまう間違いです。2番目のコマンドを実行するとシステムの/tmpディレクトリのファイルを消してしまいます。

このように相対パスと絶対パスを間違ってで実行してしまうと全く異なるディレクトリを操作してしまうため被害は甚大です。

このようなミスを犯さないための一つの方法として、echoやlsのような安全なコマンドで事前に確認します。

echo *
echo /*

このようにすれば2番目の指定が間違っていることに気づくでしょう。

また単独の*などはなるべく使わずに、もっと細かな指定も検討しましょう。

まとめ

ワイルドカードはファイルグロブ(あるいは単にグロブ)とも呼ばれます。プログラミング言語ではファイルグロブという用語が使われていることがありますので、この用語についても覚えておきましょう。

繰り返しになりますがうっかりミスには十分に気をつけましょう。コマンドを実行する前に一呼吸置いて確認することや、前述のように安全なコマンドで確認する癖をつけましょう。

-シェルスクリプト

Copyright© アナグマのモノローグ , 2022 All Rights Reserved Powered by STINGER.