如何只找到文件夹 "Pricelist" 和 "Price List" 下的 PDF 文件?

How can I find just the PDF files under folders "Pricelist" and "Price List"?

我有一个任务是在Windows7上使用JRuby找出几个价目表文件夹下的所有PDF文件。文件夹结构如下:

WorkSpace/Data/2015/city1/A/...
WorkSpace/Data/2015/city1/B/...
WorkSpace/Data/2015/city1/Pricelist/...
WorkSpace/Data/2015/city1/...
WorkSpace/Data/2015/city1/Price List/.....
WorkSpace/Data/2015/city2/A/...
WorkSpace/Data/2015/city2/C/...
WorkSpace/Data/2015/city2/Pricelist/...
WorkSpace/Data/2015/city2/D/...
WorkSpace/Data/2015/city2/Price List/.....

WorkSpace/Data/2016/city1/folder1/...
WorkSpace/Data/2016/city1/folder2/...
WorkSpace/Data/2016/city1/Pricelist/...
WorkSpace/Data/2016/city1/folder3/...
WorkSpace/Data/2016/city1/folder4/Price List/...
WorkSpace/Data/2016/city2/folder1/...
WorkSpace/Data/2016/city2/folder2/...
WorkSpace/Data/2016/city2/Pricelist/...
WorkSpace/Data/2016/city2/folder3/...
WorkSpace/Data/2016/city2/folder4/Price List/...

...表示对应文件夹下的各种文件。

我只想找到文件夹 PricelistPrice List 下的 PDF 文件。我该怎么做?

我读了Searching a folder and all of its subfolders for files of a certain type。这是一个我认为有帮助的答案,但我如何修改表达式 /.*\.pdf$/ 以实现我的目标?

您可能想要查看 Find module。代码将是这样的:

results = []
directory_list = []

Find.find('Workspace/Data') do |path|
    if FileTest.directory?(path)
        fn = File.basename(path)
        if fn == 'Pricelist' || fn == 'Price List'
            directory_list << path
            Find.prune
        end
    end
end

directory_list.each do |starting_path|
    Find.find(starting_path) do |path|
        if File.extname(path) == '.pdf'
            results << path
        end
    end
end

第一个循环扫描并找到所有符合目录名称条件的目录,跳过它们下面的扫描,因为这将在第二个循环中发生。第二个循环获取第一个循环找到的每个目录并扫描它们以查找以“.pdf”扩展名结尾的文件,将每个文件添加到结果列表中。

您可以将第二个循环的主体提升到第一个循环中代替 directory_list << path,但生成的代码将更难阅读并且不会获得任何性能改进。

使用递归 Glob

您只需 Dir#glob and Enumerable#grep 即可找到您的文件。例如:

Dir.glob('WorkSpace/Data/**/*.pdf').grep /Price List|Pricelist/

这将使用递归 glob 模式收集所有 PDF 文件,该模式下降到从 Workspace/Data 开始的所有子目录(根据需要调整此起始目录的路径),然后 returns 只有匹配您正在搜索的目录的结果。在这种情况下,我们使用交替的正则表达式模式来查找您要查找的两个目录中的任何一个,而不考虑所需目录的嵌套深度。

可能有更有效的方法来做到这一点,或者如果正则表达式对您来说过于宽容,您可能需要调整正则表达式,但这确实可以解决问题,而无需了解比目录树的根目录更多的信息想搜索。