したいこと
カレントディレクトリに存在するファイル・ディレクトリの名前を取得したい。隠しファイルの名前も取得したい。
※以下、この記事中ではファイルという呼び方ばかり使っていますが、基本的にディレクトリも含んでいると考えてください
Dirクラス
結論から言うと、Dir
クラスのglob
メソッドをつかえばいけます。
どう書けばいいかを端的に知りたい方は一番下までスクロールしてもらえればすぐコードが見られます。
docs.ruby-lang.orgdocs.ruby-lang.org
ワイルドカードの展開を行い、パターンにマッチするファイル名を文字列の配列として返します。パターンにマッチするファイルがない場合は空の配列を返します。 ブロックが与えられたときはワイルドカードにマッチしたファイルを引数にそのブロックを 1 つずつ評価して nil を返します
とのこと。
書式としてはglob(pattern, flags = 0, base: nil, sort: true)
のようになりますが、第1引数のpattern
以外は省略できます。
指定したワイルドカードのパターンと一致するファイル名を配列にして返してくれるメソッドです。
第1引数に指定できるワイルドカードは以下のとおり。
記号 | 意味 |
---|---|
* | 空文字列を含む任意の文字列 |
? | 任意の一文字 |
[] | 鈎括弧内のいずれかの文字 |
{} | コンマで区切られた文字列の組合せに展開 |
**/ | ワイルドカード */ の0回以上の繰り返し |
正直**/
とかはよく分からないけど今回は割愛。
で、今回のタイトルにあるとおりカレントディレクトリに存在する全てのファイルとディレクトリの名前を取得したい場合は、とにかく全ての文字列にマッチしてくれればいいので*
を使ってDir.glob("*")
とすればおk。秒殺。
ただし、ワイルドカードはデフォルトの挙動としてファイル名の先頭にある.
にマッチしないようになっています。
つまり隠しファイルにはマッチしません。
でも隠しファイルの名前も含めて取得する必要がある場合もあると思います。
そんなときに使えるのが第2引数。
この部分にフラグを指定してやればマッチの挙動を変更できます。
フラグってなんやねんと思われる向きもあると思います。僕も思いました。 なので簡単に書いておきます。
File.fnmatch
リファレンスマニュアルでは、glob
メソッドの第2引数で使用できるフラグというのはFile
クラスのfnmatch
メソッドで使用されるものと同じだと説明されています。
ではFile
クラスのfnmatch
メソッドとは何でしょう。
これもリンクを貼っておきます。
ファイル名のパターンマッチ fnmatch(3) を行います。 path が pattern にマッチすれば真を返します。そうでない場合には false を返します。
というわけで、今回使っているDir.glob
と似たようなメソッドで、ワイルドカードにマッチするファイル名を返してくれます。
Dir.glob
との細かい違いについては上記のリンクを参照してください。
肝心のフラグについてですが、以下の種類があります。
フラグ | 使用時の挙動 |
---|---|
FNM_NOESCAPE | エスケープ文字 \ を普通の文字とみなす |
FNM_PATHNAME | ワイルドカード * , ? , [] が / にマッチしなくなる |
FNM_CASEFOLD | アルファベットの大小文字を区別せずにパターンマッチを行う |
FNM_DOTMATCH | ワイルドカード * , ? , [] が先頭の . にマッチするようになる |
FNM_EXTGLOB | {} 内のコンマで区切られた文字列の組合せにマッチするようになる |
そのままドンピシャで書いていますが、今回のように隠しファイルにもマッチしてほしい場合にはFNM_DOTMATCH
を第2引数で使用すればいいということになります。
これらは定数で、File::FNM_NOESCAPE
のような形で使用できます。
というわけで、隠しファイルも含めたカレントディレクトリのファイル名を取得するには、
Dir.glob("*", File::FNM_DOTMATCH)
とすればおkです。
息子さんが隠しているあんなファイルやこんなファイルも全て衆目に晒すことができます。いともたやすく行われるえげつない行為(D4C)ですね。
では、今回はこんな感じです。 最後まで読んでいただきありがとうございました。