关于ruby:在文件夹及其所有子文件夹中搜索特定类型的文件

Searching a folder and all of its subfolders for files of a certain type

我试图在给定文件夹中搜索给定类型的所有文件(例如.pdf),并将其复制到新文件夹中。我需要做的是指定一个根文件夹,并在该文件夹及其所有子文件夹中搜索与给定类型(.pdf)匹配的任何文件。任何人都能帮我搜索根文件夹的子文件夹及其子文件夹等吗?这听起来像是一个递归方法可以在这里完成这个技巧,但是我不能正确地实现它?(顺便说一下,我正在Ruby中实现这个程序)。


试试这个:

1
Dir.glob("#{folder}/**/*.pdf")

这和

1
Dir["#{folder}/**/*.pdf"]

其中folder变量是要搜索的根文件夹的路径。


您需要查找模块。Find.find采用一个包含路径的字符串,并将父路径连同每个文件和子目录的路径传递到一个附带的块。一些示例代码:

1
2
3
4
5
6
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

1
2
3
4
5
6
7
8
9
10
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

nbsp;

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
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]


作为对Jergason和Matt上述答案的一个小小改进,下面介绍如何将其浓缩为一行:

1
pdf_file_paths = Find.find('path/to/search').select { |p| /.*\.pdf$/ =~ p }

它使用上面的find方法,但利用结果是可枚举的(因此,我们可以使用select)这一事实,用匹配集返回数组。