代码之家  ›  专栏  ›  技术社区  ›  or9ob

如何使Ruby找到.find跟随符号链接?

  •  8
  • or9ob  · 技术社区  · 14 年前

    我有一个文件层次结构,一些子目录是相对的符号链接。我正在使用 Ruby's Find.find 在这些目录中爬行并找到一些特定的文件。但是,它不查找任何属于symlink的目录(它跟踪的文件是symlinks)。

    看着 source code 问题似乎是因为它正在使用 File.lstat(file).directory? 测试某个东西是否是目录。这种回报 false 对于符号链接,但是 File.stat.directory? 收益率 true .

    我该怎么做 找到 遵循符号链接,除了猴子修补它 File.stat 而不是 File.lstat ?

    6 回复  |  直到 7 年前
        1
  •  5
  •   user3055549    11 年前

    我遇到了类似的情况,决定走真正的道路,不需要额外的宝石。

    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")
    

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

        2
  •  3
  •   Futzilogik    13 年前

    使用DanielJ.Berger的文件查找库。它是红宝石。然后你可以递归地找到:

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

    注意:与文档和直觉相反,设置:follow=>false实际上会使文件::find遵循所有符号链接,至少在我的计算机上(ubuntu 10.04,ruby 1.8.7,file find 0.3.4)。

    还有许多其他的选项可用于文件::查找,例如名称模式、文件类型、atime、ctime、mtime等。请查看RDOC。

        3
  •  1
  •   ghostdog74    14 年前

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

    使 迪尔 递归查找文件,尝试双asterix Dir["**/*"]

        4
  •  1
  •   akostadinov    10 年前

    编写了另一个带有循环检查和有限递归的选项。也可以与JRuby一起工作。

    这里有一个要点: https://gist.github.com/akostadinov/05c2a976dc16ffee9cac

        5
  •  0
  •   or9ob    13 年前

    对于其他观看的人,我最终使用了 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
    
        6
  •  0
  •   fotinakis    7 年前

    下面是一个更简单、更有效的递归路径名方法版本:

    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