【问题标题】:Skip first 5 lines of CSV跳过 CSV 的前 5 行
【发布时间】:2014-08-07 19:39:02
【问题描述】:

我确信这是微不足道的,但在我拔掉头发的年龄之后,是时候让你们这些友好的 SO 人来拯救我了。

我想对正在使用 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 之前删除这些行。

【问题讨论】:

  • 除了foreach之外还有其他方法,比如open本身,它给你更多的灵活性。
  • 请参阅我上面的编辑,详细说明问题:问题
  • 如果你想处理一个非 CSV 文件,你需要手动读取它,去掉前五行,重新组合,然后将它转储回 CSV 解析器。起初您似乎在描述的是省略了前五行其他 CSV 数据。
  • 如果它是一个 CSV 文件,也许你没有把它当作正确的字符编码来阅读。我们无法确定,因为您没有提供有问题的线路,但这确实很容易发生。
  • 不,它只是文件顶部的一堆 cmets,并且鉴于 CSV 没有标准的注释行方式,因此必须对其进行预处理有点痛苦.

标签: ruby csv


【解决方案1】:
csv = CSV.open @path_to_file
csv.drop(5).each do |row|
  #doing stuff here
end

【讨论】:

  • Throws a CSV:MalformedCSVError: Illegal quoting in line 3.(这就是为什么我需要在解析 CSV 之前删除这些行)
【解决方案2】:

您应该能够通过从其他不兼容的数据构造一个有效的 CSV 字符串来绕过 CSV 模块:

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

【讨论】:

    【解决方案3】:

    我试图用一个最小的工作示例来模拟你的错误:

    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">
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2014-07-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多