解析csv文件,替换分隔符,忽略“”之间的字段内容

解析csv文件,替换分隔符,忽略“”之间的字段内容

我有一个带有分隔符的文件;;我的应用程序根据这些分隔符解析数据。字符串字段位于列之间""和列中,我可能将分隔符作为文本。我想替换该文件中的分隔符(例如将其更改为|),忽略"".示例如下:

输入:

"BARCELONA";"";"Country.666;53;98";15;19;"test";4343;63647;655848

输出

"BARCELONA"|""|"Country.666;53;98"|15|19|"test"|4343|63647|655848

答案1

为了获得精确的输出,

$ perl -MText::CSV -lpe '
    BEGIN{$p = Text::CSV->new({sep_char => ";"})} 
    $_ = join "|", map { /^\d+$/ ? $_ : qq("$_") } $p->fields() if $p->parse($_)
  ' INPUT
"BARCELONA"|""|"Country.666;53;98"|15|19|"test"|4343|63647|655848

如果你不坚持非常规引用,那么

$ csvformat -d';' -D'|' INPUT
BARCELONA||Country.666;53;98|15|19|test|4343|63647|655848

强制输入和输出引用非数字几乎按照您想要的方式工作(但显然将数字字段提升为浮点):

$ csvformat -d';' -u2 -D'|' -U2 INPUT
"BARCELONA"|""|"Country.666;53;98"|15.0|19.0|"test"|4343.0|63647.0|655848.0

答案2

更改字段中的数据并不安全。

要解析 csv 文件,您可以使用csvtool

$ echo '"BARCELONA";"";"Country.666;53";15' | csvtool -t ';' col 1- -
BARCELONA,,Country.666;53,15

或针对特定领域

$ echo '"BARCELONA";"";"Country.666;53";15' | csvtool -t ';' col 1,3 -
BARCELONA,Country.666;53    

答案3

我以为用 来做到这一点很容易awk,但最终变得有点混乱。然而,由于我努力解决这个问题,这里有一个awk利用该FPAT功能的潜在解决方案:

cat file.txt | awk -v FPAT='[^;]+|"[^"]+"' '{ for( col=1; col<=NF; col++ ) { printf "%s|", $col; } print "" }'

基本上,它使用FPAT正则表达式来定义分类为项目的内容(没有分号或引号),并|在列之间使用 ( ) 字符重新打印它们。本来我想使用该OFS选项,但看起来它与该FPAT选项配合得不太好

答案4

您可以使用GNU sed启用了扩展正则表达式的编辑器来执行此操作:

$ sed -Ee 's/(("[^"]*")+|[^;]+);/\1|/g' in.csv

相关内容