如何使用ruby从csv文件中提取多列?
现在我可以从csv文件中提取1列(第6列)。如何编辑下面的脚本以提取多个列?假设我还想提取第9列、第10列和第6列。我希望输出是这样的:第6列在输出文件的第1列,第9列在输出文件的第2列,第10列在输出文件的第3列如何使用ruby从csv文件中提取多列?,ruby,Ruby,现在我可以从csv文件中提取1列(第6列)。如何编辑下面的脚本以提取多个列?假设我还想提取第9列、第10列和第6列。我希望输出是这样的:第6列在输出文件的第1列,第9列在输出文件的第2列,第10列在输出文件的第3列 ruby -rcsv -e 'CSV.foreach(ARGV.shift) {|row| puts row [5]}' input.csv &> output.csv arr = CSV.read(FNameIn, converters: :integer).
ruby -rcsv -e 'CSV.foreach(ARGV.shift) {|row| puts row [5]}' input.csv &> output.csv
arr = CSV.read(FNameIn, converters: :integer).
map { |row| row.values_at(*cols) }
#=> [[2, 4], [7, 9], [12, 14]]
FNameOut = 't_out.csv'
CSV.open(FNameOut, 'wb') { |csv| arr.each { |row| csv << row } }
让我们首先创建一个(无标题)CSV文件:
enum = 1.step
FNameIn = 't_in.csv'
CSV.open(FNameIn, "wb") { |csv| 3.times { csv << 5.times.map { enum.next } } }
#=> 3
现在,让我们提取索引1
和3
处的列。这些列将按该顺序写入输出文件
cols = [1, 3]
现在写入CSV输出文件
ruby -rcsv -e 'CSV.foreach(ARGV.shift) {|row| puts row [5]}' input.csv &> output.csv
arr = CSV.read(FNameIn, converters: :integer).
map { |row| row.values_at(*cols) }
#=> [[2, 4], [7, 9], [12, 14]]
FNameOut = 't_out.csv'
CSV.open(FNameOut, 'wb') { |csv| arr.each { |row| csv << row } }
我们可以将其读回数组:
CSV.read(FNameOut, converters: :integer)
#=> [[2, 4], [7, 9], [12, 14]]
要从命令行执行这些操作,需要对这些操作进行简单的转换。因为
行
是一个数组,所以您的问题归结为如何从数组中选取某些元素;这与CSV无关
您可以使用:
返回字段5、6、9和10
但是,如果希望以不同的顺序显示这些拾取的字段,则更容易显式映射每个索引:
output_row = Array.new(row.size) # Or row.dup, depending on your needs
output_row[1] = row[6]
# Or, if you have used row.dup and want to swap the rows:
output_row[1],output_row[6] = row[6],row[1]
# and so on
out_csv.puts(output_row)
这假设您以前定义过
out_csv=CSV.new(STDOUT)
因为您希望在标准输出上创建新的CSV。创建一个从文件读取并写入另一个文件的普通脚本,而不是shell oneliner,否则您将遇到转义引号、逗号等问题。答案与此无关,但可能对您有用:如果您的文件有标题,您应该能够传入
headers:true
参数,然后指定所需的列,而不是它们的索引行[:first\u name]、行[:last\u name]
等。
out_csv=CSV.new(STDOUT)