如何使用sed在每个连续管道之间添加空间



我有一个这样的输入:

|non-empty|||something|||

我需要改变的是,我们的wiki引擎将正确显示它,这意味着每个"空"字段都需要有一个空间:

|non-empty| | |something| | |

我试图通过使用这样的sed来实现这一点:

sed -E -e 's/||/| |/g'

但这只在每行的第一个和第二个连续管道之间增加了一个空间(尽管有/g标志(为什么会这样,我该如何修复它?

使用sed并测试

sed ':1;s/||/| |/g;t1' file

这使用测试来保持在线上循环,在和连续的小节之间留出一个空格。

输出:

|non-empty| | |something| | |

或类似于awk

awk '{while(gsub(/||/,"| |"))1}1' file
$ echo '|non-empty|||something|||' | sed 's/||/| |/g; s/||/| |/g'
|non-empty| | |something| | |

给定|||,当您执行s/||/| |/g时,第二个|正在作为第一个替换的一部分进行处理,因此之后无法进行匹配,因此在寻找下一个||时,sed从第三个|开始,因此找不到从那里开始的||。您可以通过添加第二个s/||/| |/g来简单地解决问题,因为它将从行的开头重新开始,并替换第一次传递中未找到/替换的所有||

您就快到了,只需将其更改为:

sed -E -e 's-||- | | -g'

请注意,只要一致,就可以使用任何字符作为分隔符。在这里,我将/替换为-,以使其更加清晰。

您可以使用awk进行以下操作:

s='|non-empty|||something|||'
awk 'BEGIN{FS=OFS="|"} {for (i=2; i<=NF; i++) if ($i == "") $i = " "} 1' <<< "$s"
|non-empty| | |something| | |

/g标志为"全局匹配":在同一行中匹配多次模式。如果有三个管道,则带有两个管道的图案将与前两个管道匹配,并让最后一个管道单独存在。如果有四个连续的管道,则将匹配前两个管道,然后匹配最后两个管道:||||变为| || |

/g不是递归标志。您想要递归地用| |替换||。要做到这一点,你需要使用标签和测试:答案来自@999999999999999999999999999999是一个很好的sed。

sed 's/|/| /g;s/| ([^|])/|1|/g' YourFile

在所有|之后添加一个空格,删除|之后没有|的空格。通过这种方式,在不排除下一个管道的情况下,不会处理递归和每个管道。Posix也符合

最新更新