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