2010-10-20 67 views
8

我有一个文件层次结构和一些子目录是相对符号链接。我正在使用Ruby's Find.find来抓取这些目录并找到一些特定的文件。但是它没有查看任何符号链接的目录(它遵循符号链接的文件)。如何使Ruby的Find.find遵循符号链接?

望着看来问题的source code是因为它使用File.lstat(file).directory?测试某一个目录。这将返回false的符号链接,但File.stat.directory?返回true

如何让Find.find遵循符号链接,短缺猴子修补它使用File.stat而不是File.lstat

回答

0

对于别人看着,我结束了使用Pathname和下面的递归代码:

def all_files_under(*paths) 
    paths.flatten! 
    paths.map! { |p| Pathname.new(p) } 
    files = paths.select { |p| p.file? } 
    (paths - files).each do |dir| 
    files << all_files_under(dir.children) 
    end 
    files.flatten 
end 
1

为什么不使用Dir代替?它遵循符号链接 或者你可以尝试alib

为了Dir递归地查找文件,尝试双星号Dir["**/*"]

+0

我如何'Dir'递归查找文件?我在Dir类中看不到方法 - 我在这里错过了什么吗? – arnab 2010-10-20 23:19:08

+0

虽然“alib”似乎有类似的代码,但我从来没有听说过它 - 它不在github/gemcutter上,它的名字本身(它真的是一个“lib”)并不能激发更多的信心。你在生产代码中使用过它吗?经验如何? – arnab 2010-10-20 23:20:46

+0

Dir [“**/*”]似乎只适用于一个层次 - 我有多个层次,其中一些是符号链接。我结束了使用Pathname#children(http://ruby-doc.org/core/classes/Pathname.html#M001721) – arnab 2010-11-16 03:44:45

3

由Daniel J.伯杰使用文件查找图书馆。它可以作为Ruby宝石。然后,你可以找到递归地:

require 'rubygems' 
require 'file/find' 
File::Find.new(:follow => false).find { |p| puts p } 

NB:违背文档和直觉,设置:遵循=>假,实际上使文件::查找遵守所有符号链接,至少在我的机器上(Ubuntu的10.04,红宝石1.8.7,文件查找0.3.4)。

还有一堆可用于File :: Find的其他选项,如名称模式,文件类型,atime,ctime,mtime等。请查看RDoc。

+0

谢谢。我最终使用递归函数Pathname来做到这一点。我将在下一次进入该代码库时尝试此操作(我的问题来自2010年10月)。 – arnab 2011-04-16 22:21:10

5

我遇到了类似的情况,并决定跟随无需额外的宝石真实路径。

require 'find' 

paths = ARGV 

search_dirs = paths.dup 
found_files = Array.new 

until search_dirs.size == 0 
    Find.find(search_dirs.shift) do |path| 
    if File.directory?(path) && File.symlink?(path) 
     search_dirs << File.realdirpath(path) 
    else 
     found_files << path 
    end 
    end 
end 

puts found_files.join("\n") 

这种方式不能保留原来的路径与符号链接,但目前对我来说很好。

0

这里是递归的路径名方法的更简单,更有效的版本:

def find_files(*paths) 
    paths.flatten.map do |path| 
    path = Pathname.new(path) 
    path.file? ? [path.to_s] : find_files(path.children) 
    end.flatten 
end