Awk一次性进行多个分隔符的转换。

3

我需要转换(预处理)一个CSV文件,通过生成/插入一个新列,并将现有列的内容合并为新列。

例如,将以下内容进行转换:

A|B|C|D|E

into:

A|B|C|D|C > D|E

在这个例子中,我使用了:
cat myfile.csv | awk 'BEGIN{FS=OFS="|"} {$4 = $4 OFS $3" > "$4} 1'

现在我需要完成更复杂的任务,但是不知道该怎么做。

我需要进行转换:

A|B|C|x,y,z|E

转换为

A|B|C|x,y,z|C > x,C > y,C > z|E

如何以高效的方式在awk(或其他命令)中完成此操作(我的CSV文件可能包含数千行)?

谢谢。


如果C、x、y或z可以包含任何正则表达式元字符或&\\1,请确保使用任何使用*sub()函数的解决方案来测试它们。 - Ed Morton
3个回答

3
使用GNU的awk(因为它具有GNU扩展的gensub函数):
awk -F'|' '{$6=$5; $5=gensub(/(^|,)/,"\\1" $3 " > ","g",$4); print}' OFS='|'

3

您可以将第四个字段拆分为一个数组:

awk 'BEGIN{FS=OFS="|"} {split($4,a,",");$4="";for(i=1;i in a;i++)$4=($4? $4 "," : "") $3 " > " a[i]} 1' myfile.csv
A|B|C|C > x,C > y,C > z|E

到目前为止,这是唯一的解决方案,适用于$3或$4中的任何字符/字符串,因为它只使用了字面字符串操作。 - Ed Morton

2
有许多方法可以做到这一点,但最简单的方法是以下内容:
$ awk 'BEGIN{FS=OFS="|"}{t=$4;gsub(/[^,]+/,$3" > &",t);$4 = $4 OFS t}1'

我们将第四个字段复制到变量中。在其中,我们通过第三个字段的内容加上“>”和原始匹配的字符串(“&”)来替换不包含新分隔符(“,”)的每个字符串。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接