lsやfindの「*」は正規表現じゃないの?


正規表現ワイルドカード の区別がついていませんでした。

以下の例題は、『Linux教科書 LinuCレベル1 Version 10.0対応』の模擬試験より。

例題

以下のディレクトリでls file[123]*3*を実行したとき、表示結果はどうなるか。

$ ls
file3
file3.txt
file313
file33
file33.txt

誤答のプロセス

file[123]*3*ということは、

  • fileが含まれる
  • つぎに、「1,2,3」のどれかが0個以上含まれる
  • つぎに、「3」が0個以上含まれる

だから、

  • file3 -> 一致する
  • file3.txt -> 一致する
  • file313 -> 一致する
  • file33 -> 一致する
  • file33.txt -> 一致する

「なんだ、ひっかけ問題か。全部正解ね」と答えていました。

正答

しかし実際の答えは、

$ ls file[123]*3*
file313
file33
file33.txt

であり、「file3」、「file3.txt」は一致しません。

理由

file[123]*3*正規表現だと判断したことが誤りでした。

具体的には、lsコマンドやfindコマンドでは正規表現は利用できません。

では上の場合のアスタリスクは何なのか。それが「ワイルドカード」です。

ワイルドカード

このアスタリスク(ワイルドカード)は、それ単体で「任意の文字列」を表します。

ワイルドカードでは「任意の複数文字に一致」ですが、正規表現では「直前の文字を0回以上繰り返したものに一致」です。
https://www.atmarkit.co.jp/ait/articles/0112/04/news003_2.html より

つまりfile[123]*3*は、

  • fileから始まる (このエントリでは省略しますが、正規表現ではないので「含まれる」でなく「始まる」が正解)
  • つぎに「1,2,3」のどれかが入る
  • 任意の文字列がある
  • 「3」が含まれる
  • 任意の文字列がある

と読み解くのが正解です。よって、

  • file3 -> 「1,2,3」のどれかが入ったあと、「3」が含まれない
  • file3.txt -> 「1,2,3」のどれかが入ったあと、「3」が含まれない
  • file313 -> 「1,2,3」のどれかが入ったあと、任意の文字列があり、「3」が入る
  • file33 -> 「1,2,3」のどれかが入ったあと、任意の文字列(0文字)があり、「3」が入る
  • file33.txt -> 「1,2,3」のどれかが入ったあと、任意の文字列(0文字)があり、「3」が入り、任意の文字列がある

となり、正答の通りであることを確認できました。

ちなみに

この参考書(初版)にはいくつか誤字・脱字があったので、「なんだ、これも誤ってるじゃないか」と思って調べたのが学習のキッカケでした。

人を疑う前に自身を疑うべき、というのも教訓のひとつでした。

さらにそういえば、ファイル検索するときはfind test*.txtみたいに検索していました。試験勉強のせいか、「お、これは正規表現を問う種類のやつだな」と深読み(?)していたのも誤答の原因です。

似たような疑問を持った方が読んで納得してくれれば!