我的目标是将CSV文件的一列导入Ruby数组。这适用于自包含的Ruby脚本,而不是应用程序。我将在终端中运行脚本并获得输出。
我无法找到导入文件的最佳方法,并找到将文件名称动态插入该行代码的最佳方法。文件名每次都不同,并由用户传递。我正在使用$stdin.gets.chomp
向用户询问文件名,并将其设置为file_name
。
有人可以帮我吗?以下是我对这部分剧本的看法:
require 'csv'
zip_array = CSV.read("path/to/file_name.csv")
我需要能够在上面插入正确的文件路径。它是否正确?我如何在那里获得该路径名?也许我需要完全重新构建我的脚本,但有关如何执行此操作的任何建议吗?
答案 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
希望这会有所帮助。