首页 > 解决方案 > 仅在 sed 中用双引号之间的下划线替换逗号

问题描述

假设我有这种线

aaaaa,bbbbb,"ccc,ccc","ddd,ddd,ddd",eee

我想用下划线替换逗号,但只能在双引号字段中:

aaaaa,bbbbb,"ccc_ccc","ddd_ddd_ddd",eee

当我使用:

sed 's/(\"[^\",][^\",]*),/\1_/g'

我明白了

aaaaa,bbbbb,"ccc_ccc","ddd_ddd,ddd",eee

如您所见,它适用于第三个字段,但对于第四个字段,仅替换第一个逗号。我想告诉 sed 在同一字段上“回溯”和“重新运行”多次,以替换该字段中的所有逗号(可能超过 2 个......)。我进行了广泛的搜索,但没有成功...

在此先感谢 Stephane(我的 Hello 简介已被自动删除!?)

标签: regexsed

解决方案


我建议使用perl该任务,因为有一种简单的方法可以替换内部匹配项:

perl -i -pe 's{"[^"]+"}{$&=~s/,/_/gr}ge' file

"[^"]+"匹配字符之间的字符块,"并用内部匹配$&=~s/,/_/gr替换每个字符。,_

你也可以用 GNU 来做到这sed一点:

sed -i 's/"[^"]*"/\n&/g;:a;s/\(\n"[^"]*\),/\1_/g;ta;s/\n//g' file

请参阅在线演示

在这里,s/"[^"]*"/\n&/g在双引号子字符串之前添加一个换行符,:a设置一个标签来跟踪当前匹配的开始位置,s/\(\n"[^"]*\),/\1_/g替换一个换行符 , ", 0+ non- "s (Group 1) and a ,with Group 1 value and _, 然后 - 如果替换成功 -ta跳回a标签位置,否则s/\n//g将删除双引号子字符串之前引入的换行符。


推荐阅读