跳过前5行CSV

时间:2014-08-07 19:39:03

标签: ruby csv

我确信这是微不足道的,但经过一段时间拉扯我的头发,是时候让你友好的人们救我了。

我想操作我正在使用CSV类阅读的CSV文件,如下所示:

CSV.foreach(@path_to_file) do |row|
    #doing stuff here
end

但是文件在标题上方有5行需要删除(遇到这些行时foreach方法barfs)。

我猜我可以读取文件并在没有前5行的情况下重新组装,但我确信这样做的方式更为优雅。

CSV方法不起作用的原因是前5行是CSV类不喜欢的字符;它返回CSV:MalformedCSVError: Illegal quoting in line 3

所以我认为我不能使用CSV类,除非我可以在尝试解析CSV之前删除这些行。

3 个答案:

答案 0 :(得分:6)

您应该可以通过从其他不兼容的数据构建有效的CSV字符串来绕过CSV模块:

CSV.parse(File.readlines(path).drop(5).join) do |row|
  # ...
end

答案 1 :(得分:0)

csv = CSV.open @path_to_file
csv.drop(5).each do |row|
  #doing stuff here
end

答案 2 :(得分:0)

我尝试通过一个最小的工作示例来模拟您的错误:

require 'csv'

CSV.parse(DATA.read,:col_sep=>';',:headers=>true,
  ) do |row|
  p row
end

__END__
a;b;c;d
1;2;3;4
here we have an error because there is a " in the text;
1;2;3;4
"1";"2";3;4

这将返回与您相同的错误:Illegal quoting in line 3. (CSV::MalformedCSVError)

当您知道是哪个字符串引起问题时,可以使用选项:skip_lines跳过该行:

require 'csv'

CSV.parse(DATA.read,:col_sep=>';',:headers=>true,
    :skip_lines=> /a " in the text/
  ) do |row|
  p row
end

__END__
a;b;c;d
1;2;3;4
here we have an error because there is a " in the text;
1;2;3;4
"1";"2";3;4

结果:

#<CSV::Row "a":"1" "b":"2" "c":"3" "d":"4">
#<CSV::Row "a":"1" "b":"2" "c":"3" "d":"4">
#<CSV::Row "a":"1" "b":"2" "c":"3" "d":"4">

如果您的CSV没有引号内容(在"内部),那么您也可以尝试使用未使用的字符作为qoute字符:

require 'csv'

CSV.parse(DATA.read,:col_sep=>';',:headers=>true,
    quote_char: '§'
  ) do |row|
  p row
end

__END__
a;b;c;d
1;2;3;4
here we have an error because there is a " in the text;
1;2;3;4
"1";"2";3;4

我的示例的结果也显示了,如果使用引号的内容会发生什么(请参见最后一行):

#<CSV::Row "a":"1" "b":"2" "c":"3" "d":"4">
#<CSV::Row "a":"here we have an error because there is a \" in the text" "b":nil "c":nil "d":nil>
#<CSV::Row "a":"1" "b":"2" "c":"3" "d":"4">
#<CSV::Row "a":"\"1\"" "b":"\"2\"" "c":"3" "d":"4">