Linux 从CSV数据值中删除回车符

Linux 从CSV数据值中删除回车符,linux,perl,awk,sed,text-processing,Linux,Perl,Awk,Sed,Text Processing,我使用LOAD data INFILE语句将数据从以管道分隔的CSV导入MySQL。我正在使用'\r\n'终止线路。我的问题是,每行中的某些数据中都有“\r\n”,从而导致加载出错。我有一些类似的文件,它们只是在数据中使用“\n”来表示换行符,这不会导致任何问题 示例良好CSV School|City|State|Country\r Harvard University|Cambridge|MA|USA\r Princeton University|Princeton|New Jersey |U

我使用LOAD data INFILE语句将数据从以管道分隔的CSV导入MySQL。我正在使用'\r\n'终止线路。我的问题是,每行中的某些数据中都有“\r\n”,从而导致加载出错。我有一些类似的文件,它们只是在数据中使用“\n”来表示换行符,这不会导致任何问题

示例良好CSV

School|City|State|Country\r
Harvard University|Cambridge|MA|USA\r
Princeton University|Princeton|New
Jersey
|USA\r
示例错误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,以清除列值中的额外回车?

对于多字符RS和RT,使用GNU awk:

$ 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

这是perl中一种可能的解决方案。它在一行中读取,如果少于4个字段,它将继续在下一行中读取并合并它,直到有4个字段为止。只需将
$number\u 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";
    }
#/usr/bin/perl
严格使用;
使用警告;
我的$number_of_字段=4;
while()
{
s/[\r\n]//g;
我的@fields=split(/\ |/);
下一个if($#字段==-1);

虽然($#很遗憾,fieldsYes已设置。这是我收到的格式,我无法更改它。行中的字段数是否固定?@ChrisTurner是的,行数是固定的fields@EdMorton是的,我可以确定哪个字段通常包含多行数据。抱歉,Ed,我不知道您编辑了我的原始问题。已还原回.