使用linux命令清理CSV文件,同时忽略引号之间的逗号

时间:2013-08-19 17:16:24

标签: linux csv quotes

我有一个相当大的CSV文件,偶尔需要导入PostgreSQL数据库,但它实际上总是包含太多错误,无法使用SQL COPY命令导入。通过使用此awk命令,我已设法通过引号来解决问题:

  

awk -F \“'NF%2 == 1 {print $ 0}'./ db_downloaded.csv> ./db_sanitized.csv

这会删除任何带有奇数引号的行,并且效果很好。我遇到的另一个常见问题是列数不正确。我目前解决这个问题的方法是使用以下awk命令删除任何逗号数错误的行:

  

awk -F“,”'NF == 40 {print $ 0}'./ db_sanitized.csv> ./db_sanitized2.csv

然而,这使得它删除引号之间有逗号的任何行,实际上是几行。现在,导入每一行并不是那么重要,但是我真的很喜欢它,如果我有办法只计算一行中没有出现在引号之间的逗号。我能想到的唯一方法是使用某种布尔变量,每当流中有引号时都会翻转,这会关闭检查逗号,但我不知道如果我是的话我会从哪里开始要做那件事。

我最感兴趣的是使用像grep,awk,tr等linux命令,我可以在远程服务器上运行,而不是编写自己的C ++程序,但如果没有其他的话,我可能不得不走这条路。方式。

编辑:我最终使用了这个ruby脚本:

lines = File.new("/home/db/product_list.csv", "r")
sanitized = File.new("/home/db/product_list_sanitized.csv", "w")

lines.each do |l|
  if l.count("\"") % 2 == 0
    if l.count(",") > 39
      u = true
      commas = 0
      l.each_char do |c|
        if (c == "\"")
          u = (not u)
        elsif (u && (c == ","))
          commas += 1
        end
      end
      sanitized.write(l) if commas == 39
    else
      sanitized.write(l)
    end
  end
end

sanitized.close

1 个答案:

答案 0 :(得分:0)

存储原始行,用更好的令牌替换所有引号集,然后检查;打印原件如果匹配:

awk -F, '{line=$0;gsub(/"[^"]*"/,"x")}NF%2{print line}' test.in