2016-09-19 3 views
1

特定のファイル/ディレクトリが別のディレクトリ(またはそのサブディレクトリの1つ)にあるかどうかを確認するにはどうすれば良い方法ですか?プラットフォーム独立性と絶対パス/相対パスの取り扱いは素晴らしいでしょう。ファイル/フォルダがRubyのサブディレクトリにあるかどうか確認してください

簡単な方法の1つは、ファイルを検索して毎回確認することですが、おそらくもっと良い方法があります。

与えられたディレクトリAは、Bを根とするディレクトリサブツリーの任意の場所にあるAです。つまり、is_underneath?(A,B)などです。

答えて

2

私はあなたの質問が正しいことを理解していただきたいと思います。

例:

require 'pathname' 

A = '/usr/xxx/a/b/c.txt' 
path = Pathname.new(A) 

[ 
    '/usr/xxx/a/b', 
    '/usr/yyy/a/b', 
].each{|b| 

    if path.fnmatch?(File.join(b,'**')) 
    puts "%s is in %s" % [A,b] 
    else 
    puts "%s is not in %s" % [A,b] 
    end 
} 

結果:

/usr/xxx/a/b/c.txt is in /usr/xxx/a/b 
/usr/xxx/a/b/c.txt is not in /usr/yyy/a/b 

ソリューションはclass Pathnameを使用しています。その利点:Pathnameは、ファイルシステム上のファイルまたはディレクトリの名前ですが、ファイル自体は表しません。したがって、ファイルへの読み取りアクセスなしでテストを行うことができます。

テスト自体はPathname#fnmatch?とglob-pattern File.join(path,'**')**はすべてのサブディレクトリを意味します)で行います。

あなたはより頻繁にそれが必要な場合は、Pathnameを拡張することができます:

require 'pathname' 
class Pathname 
    def is_underneath?(path) 
    return self.fnmatch?(File.join(path,'**')) 
    end 
end 

A = '/usr/xxx/a/b/c.txt' 
path = Pathname.new(A) 

[ 
    '/usr/xxx/a/b', 
    '/usr/yyy/a/b', 
].each{|b| 
    if path.is_underneath?(b) 
    puts "%s is in %s" % [A,b] 
    else 
    puts "%s is not in %s" % [A,b] 
    end 
} 

絶対/相対pathesを処理するために、それは(申し訳ありませんが、これはテストされていない)のようpathesを拡大するのを助けることができます。

class Pathname 
    def is_underneath?(path) 
    return self.expand_path.fnmatch?(File.expand_path(File.join(path,'**'))) 
    end 
end 
2

Dirクラスで提供されるglobメソッドをRuby stdlibに使用するのが素早く簡単です。

glob(pattern, [flags]) # => matches 

パターンの配列またはパターン列であるパターンを展開し、一致した又はブロックに指定された引数として結果を返します。

ファイルとディレクトリの両方で動作し、再帰的に検索することができます。 パターンと一致するファイル/ディレクトリを持つ配列を返します。一致しない場合は空になります。

root = '/my_root' 
value = 'et_voila.txt' 

Dir.glob("#{root}/**/#{value}") 

# ** Matches directories recursively. 

# or you can pass also the relative path 
Dir.glob("./foo/**/#{value}") 
関連する問題