使用awk替换字段中最后一个字符的出现。

6

我将使用awk替换字段中的最后一个字符。给定的文件如下:

John,Doe,Abc fgh 123,Abc
John,Doe,Ijk-nop 45D,Def
John,Doe,Qr s Uvw 6,Ghi

我想用逗号“,”替换最后一个空格“ ”,基本上将字段分成两部分。结果应该是这样的:
John,Doe,Abc fgh,123,Abc
John,Doe,Ijk-nop,45D,Def
John,Doe,Qr s Uvw,6,Ghi

我尝试创建一个变量,用于计算字段中空格的出现次数:

{var1=gsub(/ /,"",$3)}

并将其集成进去。
{var2=gensub(/ /,",",var1,$4); print var2}

但是gensub函数中的how-argument除了数字和G/g之外,不允许包含任何字符。

我在这里找到了一个类似的主题,但无法将其解决方案适应到我的问题上。

我相当新手,所以任何帮助都将不胜感激!


awk程序:{n=gsub(/ /," ",$3);newv=n?gensub(/ /,",",n,$3):newv;print newv;}应该可以正常工作。是什么让你认为它不能正常工作? - rici
3个回答

4

使用GNU awk中的gensub()函数:

$ awk 'BEGIN{FS=OFS=","} {$3=gensub(/(.*) /,"\\1,","",$3)}1' file
John,Doe,Abc fgh,123,Abc
John,Doe,Ijk-nop,45D,Def
John,Doe,Qr s Uvw,6,Ghi

请获取Arnold Robbins编写的《Effective Awk编程》一书。

顺便说一下,这是非常好的问题!


2
这里有一个简短的 awk
awk '{$NF=RS$NF;sub(" "RS,",")}1' file
John,Doe,Abc fgh,123,Abc
John,Doe,Ijk-nop,45D,Def
John,Doe,Qr s Uvw,6,Ghi

根据Ed的评论进行更新。

或者您可以使用rev工具。

rev file | sed 's/ /,/' | rev
John,Doe,Abc fgh,123,Abc
John,Doe,Ijk-nop,45D,Def
John,Doe,Qr s Uvw,6,Ghi

将该行反转,然后用,替换第一个空格,最后再次反转。


awk 版本可能存在的问题是,将 $NF 赋值后,该行将重新组合,这可能会影响具有多个空格的行。类似 John,Doe,Qr.....s Uvw 6,Ghi 的内容将被输出为 John,Doe,Qr.s Uvw,6,Ghi,而不是 John,Doe,Qr.....s Uvw,6,Ghi。(其中 Qrs 之间的点是空格,在注释中会被折叠,有些讽刺)。当然,如果输入没有这个问题,那么避免使用仅适用于 gawk 的 gensub 和正则表达式非常好! - jas

0
一个非常奇怪的解决办法,但只适用于最后一个单个空格:
GA 41 RICO —> GA 41 ,RICO
 mawk 'NF < 2 || $NF = substr($0, length($1) + 2)' FS=' [^ ]*$' OFS=,           

John,Doe,Abc fgh,123,Abc
John,Doe,Ijk-nop,45D,Def
John,Doe,Qr s Uvw,6,Ghi

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