我有一个这样的输入:
|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也符合