如果数据中不存在定界符值,请删除双引号

use*_*267 1 csv perl awk sed

给出了一个输入文件,该文件的每一行包含每一列的引号和回车符/换行符。

  • 如果该行包含新行,则将其附加在引号内的同一行中,例如,第1行

  • 如果没有定界符(,),则删除每列的双引号。

  • 删除回车符,即(^ M)

为了举例,给出以下输入文件

"name","address","age"^M
"ram","abcd,^M
def","10"^M
"abhi","xyz","25"^M
"ad","ram,John","35"^M
Run Code Online (Sandbox Code Playgroud)

我想通过sed / perl / awk脚本/ oneliner获得以下输出。

name,address,age
ram,"abcd,def",10
abhi,xyz,25
ad,"ram,John",35
Run Code Online (Sandbox Code Playgroud)

到目前为止我已经累了的解决方案用于附加上一行

sed '/^[^"]*"[^"]*$/{N;s/\n//}' sample.txt
Run Code Online (Sandbox Code Playgroud)

用于替换Control-M字符

perl -pne 's/\\r//g' sample.txt
Run Code Online (Sandbox Code Playgroud)

但是我没有达到我下面要求的最终输出

zdi*_*dim 6

使用库来解析CSV文件。除了一直希望在此处使用库之外,您还具有非常特殊的原因,带有嵌入式换行符和定界符。

在Perl中,一个不错的库是Text :: CSV(的包装Text::CSV_XS)。一个基本的例子

use warnings;
use strict;
use feature 'say';

use Text::CSV;

my $file = shift or die "Usage: $0 file.csv\n";

my $csv = Text::CSV->new({ binary => 1, auto_diag => 1 }); 

open my $fh, '<', $file  or die "Can't open $file: $!";

while (my $row = $csv->getline($fh)) { 
    s/\n*//g for @$row; 
    $csv->say(\*STDOUT, $row);
}
Run Code Online (Sandbox Code Playgroud)

评论

  • binary构造函数中的选项允许将换行符嵌入到数据中

  • 将一行读入数组引用后,$row我将使用简单的正则表达式删除每个字段中的换行符。一定要根据需要对此进行改进

  • 修剪$row工作如下。在foreach循环中,每个元素都由loop变量别名,因此,如果更改了该元素,则数组也会更改。我使用default,其中元素以别名$_,而regex会因此而$row改变。

  • 处理后的输出将打印到,STDOUT但是您可以打开一个输出文件,然后将该文件句柄传递到say(或print在较旧的模块版本中),以便将输出直接传递到该文件

上面的印刷品,用于问题中提供的样本输入

姓名,地址,年龄
ram,“ abcd,def”,10
阿比,xyz,25
ad,“ ram,John”,35