现在,我可以从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
答案 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"
现在,让我们提取索引1
和3
处的列。这些列将按该顺序写入输出文件。
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]]
从命令行执行这些操作需要对这些操作进行直接转换。