如何将CSV文件的列导入Ruby数组?

时间:2014-09-23 18:35:24

标签: ruby arrays bash csv terminal

我的目标是将CSV文件的一列导入Ruby数组。这适用于自包含的Ruby脚本,而不是应用程序。我将在终端中运行脚本并获得输出。

我无法找到导入文件的最佳方法,并找到将文件名称动态插入该行代码的最佳方法。文件名每次都不同,并由用户传递。我正在使用$stdin.gets.chomp向用户询问文件名,并将其设置为file_name

有人可以帮我吗?以下是我对这部分剧本的看法:

require 'csv'
    zip_array = CSV.read("path/to/file_name.csv")

我需要能够在上面插入正确的文件路径。它是否正确?我如何在那里获得该路径名?也许我需要完全重新构建我的脚本,但有关如何执行此操作的任何建议吗?

3 个答案:

答案 0 :(得分:2)

我认为这里有两个问题。第一个是从命令行获取用户输入。通常的方法是使用ARGV。在您的程序中,您可以执行file_name = ARGV[0],以便用户可以在命令行上键入ruby your_program.rb path/to/file_name.csv

接下来是关于阅读CSV。使用CSV.read将获取整个CSV,而不仅仅是一列。如果你想选择一列中的一列,你可能会更好:

zip_array = []
CSV.foreach(file_name) { |row| zip_array << row[whichever_column] }

答案 1 :(得分:1)

首先,您需要将$stdin.gets.chomp的返回值分配给变量:

foo = $stdin.gets.chomp

将输入的输入分配给foo

您不需要使用$stdin,因为gets默认会使用标准输入频道:

foo = gets.chomp

此时使用变量作为read参数:

zip_array = CSV.read(foo)

这是所有基本编码,涵盖在语言的任何介绍书中。

答案 2 :(得分:1)

好的,第一个问题:

a)每次运行时文件名都不同(我猜它总是一个CSV文件,对吗?)

你可以通过在Ruby脚本中创建一个文件夹来解决这个问题,比如input_data。然后做:

Dir.glob('input_data/*.csv')

这将在该文件夹中生成以CSV结尾的所有ALL文件数组。如果我们假设该文件夹中一次只有一个文件(名称不同),我们可以这样做:

file_name = Dir.glob('input_data/*.csv')[0]

这样,无论文件名称是什么,您都将动态获取文件路径。如果csv文件与Ruby脚本位于同一目录中,则可以执行以下操作:

Dir.glob('*.csv')[0]

现在,只将1列导入Ruby数组(让我们假设它是第一列):

require 'csv'
array = []
CSV.foreach(file_name) do |csv_row|
  array << csv_row[0] # [0] for the first column, [1] for the second etc.
end

如果您的CSV文件包含标题怎么办?假设您的列名称为“总计”。你可以这样做:

require 'csv'
array = []
CSV.foreach(file_name, headers: true) do |csv_row|
  array << csv_row['Total']
end

现在无论你的列是第一列,第三列等都没关系,只要它有一个名为'Total'的标题,Ruby就会找到它。

CSV.foreach逐行读取您的文件,适用于大文件。 CSV.read将立即读取它,但使用它可以使您的代码更简洁:

array = CSV.read(, headers: true).map do |csv_row|
  csv_row['Total']
end

希望这会有所帮助。