如何使用ruby从csv文件中提取多个列?

时间:2019-09-12 23:17:14

标签: ruby

现在,我可以从csv文件中提取1列(第6列)。如何编辑下面的脚本以提取多于1列?假设我还希望提取第9列和第10列以及第6列。我希望输出是这样,第6列最终位于输出文件的第1列,第9列在输出文件的第2列,第10列在输出文件的第三列中。

ruby -rcsv -e 'CSV.foreach(ARGV.shift) {|row| puts row [5]}' input.csv &> output.csv

2 个答案:

答案 0 :(得分:2)

由于row是一个数组,因此您的问题归结为如何从数组中选择某些元素;这与CSV无关。

您可以使用values_at

row.values_at(5,6,9,10)

返回字段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。

答案 1 :(得分:1)

首先创建一个(无标题的)CSV文件:

enum = 1.step
FNameIn = 't_in.csv'

CSV.open(FNameIn, "wb") { |csv| 3.times { csv << 5.times.map { enum.next } } }
  #=> 3   

我假设文件包含整数的字符串表示形式。

文件包含三行:

File.read(FNameIn).each_line { |line| p line }
"1,2,3,4,5\n"
"6,7,8,9,10\n"
"11,12,13,14,15\n"

现在,让我们提取索引13处的列。这些列将按该顺序写入输出文件。

cols = [1, 3]

现在写入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 } }

我们写了三行:

File.read(FNameOut).each_line { |line| p line }
"2,4\n"
"7,9\n"
"12,14\n"

我们可以读回一个数组:

CSV.read(FNameOut, converters: :integer)
  #=> [[2, 4], [7, 9], [12, 14]]

从命令行执行这些操作需要对这些操作进行直接转换。