我使用LOAD DATA INFILE语句将数据从管道分隔的CSV导入MySQL。我使用'\ r \ n'来终止行。我的问题是每行中的一些数据中包含'\ r \ n',导致加载错误。我有类似的文件,只是在数据中使用'\ n'来表示换行符,这不会导致任何问题。
示例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
有没有办法使用sed,awk或perl预处理CSV,以清除列值中的额外回车符?
答案 0 :(得分: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";
}
答案 1 :(得分: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.脚本COULD通过读取第一行来计算字段数如果第一行不能解决您的问题,请输入您的输入:
$ 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