2017-10-06 32 views
0

我使用LOAD DATA INFILE语句将数据从管道分隔的CSV导入到MySQL。我正在使用'\ r \ n'来终止行。我的问题是,每行内的一些数据中有'\ r \ n',导致加载错误。我有类似的文件,只是在数据中使用'\ n'来指示换行符,并且不会引起任何问题。从CSV数据值中删除回车符

例GOOD CSV

School|City|State|Country\r 
Harvard University|Cambridge|MA|USA\r 
Princeton University|Princeton|New 
Jersey 
|USA\r 

例BAD CSV

School|City|State|Country\r 
Harvard University|Cambridge|MA|USA\r 
Princeton University|Princeton|New\r 
Jersey\r 
|USA\r 

有没有办法预先处理的CSV,使用SED,AWK或Perl,清理额外的回车在列值?

+0

是Ed,不幸的。这是我得到的格式,我没有能力改变它。 – Gavi

+0

行是否有固定数量的字段? –

+0

@ChrisTurner是有固定数量的字段 – Gavi

回答

0

随着GNU AWK多焦RS和RT:

$ awk -v RS='([^|]+[|]){3}[^|]+\r\n' -v ORS= '{$0=RT; gsub(/\r/,""); sub(/\n$/,"\r\n")} 1' file | cat -v 
School|City|State|Country^M 
Harvard University|Cambridge|MA|USA^M 
Princeton University|Princeton|New 
Jersey 
|USA^M 

注意,它假定字段数是4,所以如果你有领域的一些其他的号码,然后更改3到数减1。该脚本可以通过读取你输入的第一线,而不是计算领域的数量如果第一行不能有你的问题:

$ awk ' 
    BEGIN { RS="\r\n"; ORS=""; FS="|" } 
    FNR==1 { RS="([^|]+[|]){"NF-1"}[^|]+\r\n"; RT=$0 RT } 
    { $0=RT; gsub(/\r/,""); sub(/\n$/,"\r\n"); print } 
' file | cat -v 
School|City|State|Country^M 
Harvard University|Cambridge|MA|USA^M 
Princeton University|Princeton|New 
Jersey 
|USA^M 
1

这是perl的一个可能的解决方案。它在一行中读取,如果少于4个字段,它会继续读取下一行并合并它,直到它有4个字段。只需将$number_of_fields的值更改为正确的数字即可。

#!/usr/bin/perl 

use strict; 
use warnings; 

my $number_of_fields=4; 

while(<STDIN>) 
    { 
    s/[\r\n]//g; 
    my @fields=split(/\|/); 
    next if($#fields==-1); 

    while($#fields<$number_of_fields-1) 
     { 
     my $nextline=<STDIN> || last; 
     $nextline =~ s/[\r\n]//g; 
     my @tmpfields=split(/\|/,$nextline); 
     next if($#tmpfields==-1); 
     $fields[$#fields] .= "\n".$tmpfields[0]; 
     shift @tmpfields; 
     push @fields,@tmpfields; 
     } 
    print join("|",@fields),"\r\n"; 
    }