2

假设我们在 CSV 中有一行,如下所示:

|Foo|,,,,,,,,|Bar|,,,,,

|封装器在哪里,,分隔符在哪里(如您所料)。

但是假设您有一些代码需要填充这些空字段,而您希望将此行转换为如下内容:

|Foo|,||,||,||,||,||,||,||,|Bar|,||,||,||,||,

(我们可以稍后处理尾随逗号)我尝试在这个 CSV 上使用这个 sed 命令来获得所需的结果:

sed 's/,,/,||,/g'

然而,正则表达式模式,,不是零宽度,所以当它扫描线时,它会移动两个,即使我们只处理了一个字段。结果是这样的:

|Foo|,||,,||,,||,,||,|Bar|,||,,||,,

问题是当我们在替换中走到这一步时:

|Foo|,||,,,,,,,|Bar|,,,,,

我们已经“||处理”,||,.

如何使用 sed 进行这种替换?

4

3 回答 3

1

一个快速的解决方案是重复替换:

sed 's/,,/,||,/g;s/,,/,||,/g'
于 2013-02-08T17:06:16.833 回答
1

更优雅的方法是使用条件分支:

$ sed ':a;s/,,/,||,/;ta' <<< '|Foo|,,,,,,,,|Bar|,,,,,'
|Foo|,||,||,||,||,||,||,||,|Bar|,||,||,||,||,

来自man sed

t标签

如果 as/// 自最后一个输入行被读取并且自最后一个 t 或 T 命令以来已成功完成替换,则分支到标签;如果省略标签,则跳转到脚本末尾。

于 2013-02-08T17:17:54.017 回答
1

使用 awk 我们可以这样做

awk '{while(i<2){gsub(",,",",||,");i++}}1' temp.txt
于 2013-02-10T02:21:01.420 回答