如何使Ruby的Find.find遵循符号链接?
我有一个文件层次结构,一些子目录是相对符号链接。 我正在使用Ruby的Find.find
来浏览这些目录并找到一些特定的文件。 但是,它不会查看任何符号链接的目录(它遵循符号链接的文件)。
看看源代码似乎问题是因为它正在使用File.lstat(file).directory?
测试某些东西是否是目录。 这对符号链接返回false
但File.stat.directory?
返回true
。
如何使Find.find
跟随符号链接,缺少猴子修补它以使用File.stat
而不是File.lstat
?
我遇到了类似的情况,并决定遵循真正的道路,没有额外的gem。
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")
这种方式不能保持带有符号链接的原始路径,但此刻对我来说还不错。
使用Daniel J. Berger的文件查找库。 它可以作为Rubygem使用。 然后你可以递归地找到:
require 'rubygems' require 'file/find' File::Find.new(:follow => false).find { |p| puts p }
注意:与文档和直觉相反,设置:follow => false实际上会使File :: Find跟随所有符号链接,至少在我的机器上(Ubuntu 10.04,Ruby 1.8.7,file-find 0.3.4)。
File :: Find还有许多其他选项,比如名称模式,文件类型,atime,ctime,mtime等。看看RDoc。
为什么不使用Dir
呢? 它遵循符号链接或者你可以尝试alib
要使Dir
递归方式查找文件,请尝试使用double asterix Dir["**/*"]
用循环检查写了另一个选项,只有有限的递归。 与jruby一起使用。
这是一个要点: https : //gist.github.com/akostadinov/05c2a976dc16ffee9cac
对于其他人来说,我最终使用了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
这是一个更简单,更有效的递归Pathname方法版本:
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