2

ときどき PostgreSQL データベースにインポートする必要があるかなり大きな CSV ファイルがありますが、ほとんどの場合、SQL COPY コマンドを使用してインポートするにはエラーが多すぎます。このawkコマンドを使用して、引用符が本来あるべきではない場所にあるという問題を修正できました。

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

これにより、引用符の数が奇数の行が削除され、非常にうまく機能します。私が遭遇するもう 1 つのよくある問題は、列の数が正しくないことです。この問題に対する私の現在の解決策は、次の awk コマンドを使用して、コンマの数が間違っている行を削除することです。

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

ただし、これにより、実際にはかなりの数の行である、引用符の間にコンマがある行が削除されます。ここで、すべての行をインポートすることはそれほど重要ではありませんが、行の引用符の間に表示されなかったコンマだけをカウントする方法があれば、非常に気に入っています。これを行うために考えることができる唯一の方法は、ストリームに引用符があるたびに反転するある種のブール変数を使用することです。これにより、コンマのチェックがオフになりますが、どこから始めればよいかわかりませんそれをするつもりです。

独自の C++ プログラムを作成するのではなく、リモート サーバーで実行できる grep、awk、tr などの Linux コマンドを使用することに主に関心がありますが、他に方法がない場合は、そのルートに行かなければならない場合があります。

編集:私はこのルビースクリプトを使用することになりました:

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
4

1 に答える 1

2

元の行を隠し、引用符のすべてのセットをより適切に動作するトークンに置き換え、それに対してチェックします。一致する場合はオリジナルを印刷します。

awk -F, '{line=$0;gsub(/"[^"]*"/,"x")}NF%2{print line}' test.in
于 2013-08-20T13:31:59.660 に答える