使用Linux工具将多行csv转换为单行

sja*_*aak 5 csv bash awk sed

我有一个 .csv 文件,其中包含双引号多行字段。我需要将多行单元格转换为单行单元格。它没有显示在示例数据中,但我不知道哪些字段可能是多行的,因此任何解决方案都需要检查每个字段。我确实知道我会有多少列。第一行也需要被跳过。我不知道有多少数据,因此性能不是考虑因素。

我需要一些可以在 Linux 上通过 bash 脚本运行的东西。最好使用 awk 或 sed 等工具,而不是实际的编程语言。

数据将使用 Logstash 进行进一步处理,但它不处理双引号多行字段,因此需要进行一些预处理。

我尝试了类似的方法,它在一行上有效,但在多行上失败。

sed -e :0 -e '/,.*,.*,.*,.*,/b' -e N -e '1n;N;N;N;s/\n/ /g' -e b0 file.csv
Run Code Online (Sandbox Code Playgroud)

CSV 示例

First name,Last name,Address,ZIP
John,Doe,"Country

City
Street",12345
Run Code Online (Sandbox Code Playgroud)

我想要的输出是

First name,Last name,Address,ZIP
John,Doe,Country City Street,12345
Jane,Doe,Country City Street,67890
etc.
etc.
Run Code Online (Sandbox Code Playgroud)

tsh*_*ono 1

如果Perl这是您的选择,请尝试以下操作:

perl -e '
while (<>) {
    $str .= $_;
}

while ($str =~ /("(("")|[^"])*")|((^|(?<=,))[^,]*((?=,)|$))/g) {
    if (($el = $&) =~ /^".*"$/s) {
        $el =~ s/^"//s; $el =~ s/"$//s;
        $el =~ s/""/"/g;
        $el =~ s/\s+(?!$)/ /g;
    }
    push(@ary, $el);
}

foreach (@ary) {
    print /\n$/ ? "$_" : "$_,";
}' sample.csv
Run Code Online (Sandbox Code Playgroud)

样本.csv:

First name,Last name,Address,ZIP
John,Doe,"Country

City
Street",12345
John,Doe,"Country

City
Street",67890
Run Code Online (Sandbox Code Playgroud)

结果:

First name,Last name,Address,ZIP
John,Doe,Country City Street,12345
John,Doe,Country City Street,67890
Run Code Online (Sandbox Code Playgroud)