有没有办法在Ruby中创建一个目录但是排除某些目录?

jar*_*jar 26 ruby bash shell

我想将一个目录全局化以后处理头文件.但我想排除项目中的一些目录.现在默认方式是......

Dir["**/*.h"].each { |header|
    puts header
}
Run Code Online (Sandbox Code Playgroud)

如果它位于排除目录中,则手动检查每个标头条目似乎效率低下.

Jor*_*ell 54

我知道这已经晚了4年但是对于其他可能遇到这个问题的人来说,你可以从Dir中排除与Bash通配符相同的方式:

Dir["lib/{[!errors/]**/*,*}.rb"]
Run Code Online (Sandbox Code Playgroud)

这将排除任何以"错误"开头的文件夹,/如果你愿意,你甚至可以省略它并将其变成一种通配符.

  • 警告!这种否定并不十分准确.Ruby的[!...]实现匹配[维基百科上的这个描述](https://en.wikipedia.org/wiki/Glob_(编程)#Unix).[!errors /]匹配一个不是e,r,o,s或/的字符.`[!e] [!r] [!r] [!o] [!r] [!s] [!/]`会匹配不以"errors /"开头的字符串,但是,它不匹配字符串短于7个字符.(您可以通过在irb中创建一些名为a,aa,ab等的测试文件夹并使用Dir.glob列出它们来验证这一点). (14认同)
  • def不迟,谢谢! (2认同)

the*_*Man 24

不要使用globbing,而是使用Find.Find旨在让您在遇到目录和文件时访问它们,并以编程方式决定何时退出目录并转到下一个目录.请参阅doc页面上的示例.

如果你想继续使用globbing,这会给你一个起点.您可以将多个测试放在reject一起或放在一起:

Dir['**/*.h'].reject{ |f| f['/path/to/skip'] || f[%r{^/another/path/to/skip}] }.each do |filename|
  puts filename
end
Run Code Online (Sandbox Code Playgroud)

您可以在测试中使用固定字符串或正则表达式.

  • 也没有... .reject {| f | File.fnmatch('**.tmpl.html',f)} .each {... :) (2认同)

The*_*heo 18

FileList来自耙宝石(这几乎总是默认安装的,并且包含在Ruby 1.9的标准库):

files = FileList['**/*.h'].exclude('skip_me')
Run Code Online (Sandbox Code Playgroud)

FileList 有很多功能可以有效地使用globs.

您可以在此处找到文档:http://rake.rubyforge.org/classes/Rake/FileList.html


gro*_*ser 7

files = Dir.glob(pattern)
files -= Dir.glob("#{exclude}/**/*")
Run Code Online (Sandbox Code Playgroud)


Mar*_*mas 5

单程:

require 'find'

ignores = ['doc','test','specifications']

Find.find(ENV['HOME']) do |path|
  name = File.basename(path)
  if FileTest.directory?(path)
    if ignores.include?(name)
      Find.prune
    else
      next
    end
  else
    puts path if name =~ /.h$/
  end
end
Run Code Online (Sandbox Code Playgroud)