【问题标题】:Dir.glob to get all csv and xls files in folderDir.glob 获取文件夹中的所有 csv 和 xls 文件
【发布时间】:2013-06-01 09:21:42
【问题描述】:
folder_to_analyze = ARGV.first
folder_path = File.join(Dir.pwd, folder_to_analyze)

unless File.directory?(folder_path)
  puts "Error: #{folder_path} no es un folder valido."
  exit
end

def get_csv_file_paths(path)
  files = []
  Dir.glob(path + '/**/*.csv').each do |f|
    files << f
  end
  return files
end

def get_xlsx_file_path(path)
  files = []
  Dir.glob(path + '/**/*.xls').each do |f|
    files << f
  end
  return files
end

files_to_process = []
files_to_process << get_csv_file_paths(folder_path)
files_to_process << get_xlsx_file_path(folder_path)
puts files_to_process[1].length # Not what I want, I want:
# puts files_to_process.length

我正在尝试在 Ruby 中创建一个简单的脚本,允许我从命令行调用它,例如 ruby counter.rb mailing_list1,它会转到文件夹并计算所有 .csv 和 .xls 文件。

我打算对每个文件进行操作,获取行数等。

目前files_to_process 数组实际上是一个数组数组——我不希望这样。我想要一个包含 .csv 和 .xls 文件的数组。

由于我不知道如何从 Dir.glob 调用中产生,我将它们添加到一个数组并返回。

如何使用单个数组完成此操作?

【问题讨论】:

    标签: ruby arrays yield dir


    【解决方案1】:

    只需将文件扩展名放在一组中即可:

    Dir[path + "/**/*.{csv,xls}"]
    

    【讨论】:

    • IMO,这是一个更红宝石的答案。这是一条线,清晰易读。不过,我会这样做: Dir["#{path}/**/*.{csv,xls}] 显然是六个中的一个和另一个。
    【解决方案2】:

    嗯,让步很简单。只需yield

    def get_csv_file_paths(path)
      Dir.glob(path + '/**/*.csv').each do |f|
        yield f
      end
    end
    
    def get_xlsx_file_path(path)
      Dir.glob(path + '/**/*.xls').each do |f|
        yield f
      end
    end
    
    files_to_process = []
    get_csv_file_paths(folder_path) {|f| files_to_process << f }
    get_xlsx_file_path(folder_path) {|f| files_to_process << f }
    
    puts files_to_process.length
    

    ruby 中的每个方法都可以传递一个块。并且yield 关键字将数据发送到该块。如果可能提供也可能不提供块,yield 通常与block_given? 一起使用。

    yield f if block_given?
    

    更新

    将代码块直接传递给glob.each,可以进一步简化代码:

    def get_csv_file_paths(path, &block)
      Dir.glob(path + '/**/*.txt').each(&block)
    end
    
    def get_xlsx_file_path(path, &block)
      Dir.glob(path + '/**/*.xls').each(&block)
    end
    

    虽然这个块/过程转换是有点高级的话题。

    【讨论】:

    • @Merovex:但是请注意,这篇文章回答了我认为的直接问题(“我如何从中获得收益?”),而不是包装完整的解决方案。
    • 很公平,尽管请求的“让步”部分隐藏在叙述中。可能有助于在基本问题中提及这一点。 ;-)
    【解决方案3】:
    def get_folder_paths(root_path)
      Dir.glob('**/*.csv') + Dir.glob('**/*.xls')
    end
    
    folder_path = File.join(Dir.pwd, ARGV.first || '')
    raise "#{folder_path} is not a valid folder" unless File.directory?(folder_path)
    
    puts get_folder_paths(folder_path).length
    

    get_folder_paths 方法返回一个 CSV 和 XLS 文件数组。构建一个文件名数组可能不是您真正想要的,尤其是当它们有很多 很多 时。如果您不首先需要文件计数,那么在这种情况下,使用 Dir.glob 返回的 Enumerator 的方法会更合适。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-03-31
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多