我正在尝试在指定文件夹中搜索所有给定类型的文件并将它们复制到新文件夹。
我需要指定一个根文件夹,并在该文件夹及其所有子文件夹中搜索符合给定类型的任何文件。
如何搜索根文件夹的子文件夹及其子文件夹? 似乎递归方法可以解决问题,但我无法正确实现它。
试试这个:
Dir.glob("#{folder}/**/*.pdf")
这与
Dir["#{folder}/**/*.pdf"]
其中folder变量是你想要搜索的根文件夹的路径。
你需要使用Find模块。 Find.find
接受一个包含路径的字符串作为参数,然后将父目录路径和每个文件和子目录的路径传递给相应的代码块。以下是一些示例代码:
require 'find'
pdf_file_paths = []
Find.find('path/to/search') do |path|
pdf_file_paths << path if path =~ /.*\.pdf$/
end
这将递归搜索一个路径,并将以 .pdf 结尾的所有文件名存储在一个数组中。
Dir.glob
而不是Find.find
。Warming up --------------------------------------
Find.find 124.000 i/100ms
Dir.glob 515.000 i/100ms
Calculating -------------------------------------
Find.find 1.242k (± 4.7%) i/s - 6.200k in 5.001398s
Dir.glob 5.249k (± 4.5%) i/s - 26.265k in 5.014632s
Comparison:
Dir.glob: 5248.5 i/s
Find.find: 1242.4 i/s - 4.22x slower
require 'find'
require 'benchmark/ips'
dir = '.'
Benchmark.ips do |x|
x.report 'Find.find' do
Find.find(dir).select { |f| f =~ /\*\.pdf/ }
end
x.report 'Dir.glob' do
Dir.glob("#{dir}/**/*\.pdf")
end
x.compare!
end
使用 ruby 2.2.2p95 (2015-04-13 revision 50295) [x86_64-darwin15]
Dir.glob
和 Find.find
之间应该使用哪种方法。 - itsh#end_with?
来更仔细地比较它们.... - rogerdpackfalse
替换整个块内容,它仍然会显著变慢(试一试吧)。这是因为调用块也需要一些时间,并且对于找到的每个项目都会发生,而 glob
过滤器在内部过滤并只在收集结果完成后返回。因此,您在使用 find
时使用的过滤器可以像您喜欢的那样复杂,它可以是具有查找和多个正则表达式的100行代码,而 glob
只理解每次调用一个简单的模式。如果您可以以这种方式表达您的搜索,请优先考虑使用 glob
。 - Meckipdf_file_paths = Find.find('path/to/search').select { |p| /.*\.pdf$/ =~ p }
这里使用了与上述相同的“Find”方法,但利用了结果是可枚举的事实(因此我们可以使用“select”),以便获得一个包含匹配项集合的数组。
pdf_file_paths = `find #{dir} -name "*.pdf"`.split("\n")
无法在Windows上运行。
Dir.glob("#{folder}/**/*.pdf")
,其中变量folder
是您要搜索的根文件夹的路径。 - AutomaticoDir#[]
是我通常使用的方法。但是有一个问题:Dir.glob
会将所有路径加载到内存中。这通常没有问题,但如果您有大量路径,最好使用 Find 模块,因为它在发现路径时会将其传递给块。 - Wayne ConradFind
处理层次结构比将其抛给操作系统并潜在地获得意外数组更有效,也可能更快。调试这种情况很困难。 - the Tin Man