有没有一种简单的方法来模拟Dir :: glob?

时间:2013-05-09 10:50:10

标签: ruby

我有一个文件名列表,我想在其上实现Dir::glob

我认为这很容易,因为有File::fnmatch看起来像是正确的工具。但是,这两种方法在某些情况下表现不同:

# Given a directory layout like this:
# +
# |-- file
# |-+ folder
# | |-- file

# gives ['file','folder/file']
Dir.glob('**/file') 

# gives ['folder/file']
['file','folder','folder/file'].select{|n| File.fnmatch?('**/file', n) }

预先设置斜杠解决了这个问题,但又引入了另一个问题:

# gives ['file,'folder/file']
['file','folder','folder/file'].select{|n| File.fnmatch?('**/file','/'+n) }
# gives an empty array, but should give 'file' and 'folder' like Dir.glob does.
['file','folder','folder/file'].select{|n| File.fnmatch?('f*','/'+n) }

有人已经解决了这个问题,还是我必须做一些Regexp Magic(tm)?

3 个答案:

答案 0 :(得分:3)

您需要指向FNM_PATHNAME标记

> ['file','folder','folder/file'].select{|n| File.fnmatch?('**/file', n, File::FNM_PATHNAME) }
 => ["file", "folder/file"] 
> ['file','folder','folder/file'].select{|n| File.fnmatch?('f*',n, File::FNM_PATHNAME) }
 => ["file", "folder"] 

答案 1 :(得分:2)

尝试传递File::FNM_PATHNAME标志,

 ['file','folder','folder/file'].select{|n| File.fnmatch?('**/file', n,File::FNM_PATHNAME) }
 => ["file", "folder/file"]

这似乎给你想要的东西..

答案 2 :(得分:0)

不确定这是否适用于所有情况,但**文件(没有斜杠)似乎与您的测试用例匹配:

 ['file', 'folder', 'folder/file'].select {|n| File.fnmatch?('**file', n) }