我有这样的输入:
|non-empty|||something|||
我需要改变的方式是我们的wiki引擎会正确显示它,这意味着每个"空的"字段需要有空格:
|non-empty| | |something| | |
我试图通过像这样使用sed来实现这个目标:
sed -E -e 's/\|\|/| |/g'
但是这只在每一行的第一个和第二个连续管道之间添加了一个空格(虽然/ g标志在那里)为什么这样,我怎么能修复它?
答案 0 :(得分:2)
使用sed和测试
sed ':1;s/||/| |/g;t1' file
这使用测试来保持在线之间循环,在连续条之间放置一个空格。
输出:
|non-empty| | |something| | |
或类似的awk
awk '{while(gsub(/\|\|/,"| |"))1}1' file
答案 1 :(得分:1)
$ echo '|non-empty|||something|||' | sed 's/||/| |/g; s/||/| |/g'
|non-empty| | |something| | |
鉴于|||
,当您执行s/||/| |/g
时,第二个|
正在作为第一次替换的一部分进行处理,因此之后无法进行匹配,因此在寻找时下一个||
sed从第3 |
开始,因此从那里开始找不到||
。你可以通过添加第二个s/||/| |/g
来解决这个问题,因为它会从行的开头再次开始,并替换第一个找不到的所有||
通过。
答案 2 :(得分:0)
你几乎就在那里,只需将其改为:
sed -E -e 's-\|\|- | | -g'
请注意,只要您保持一致,就可以将任何字符用作分隔符。在这里,我将/
替换为-
以使其更清晰。
答案 3 :(得分:0)
您可以使用awk:
s='|non-empty|||something|||'
awk 'BEGIN{FS=OFS="|"} {for (i=2; i<=NF; i++) if ($i == "") $i = " "} 1' <<< "$s"
|non-empty| | |something| | |
答案 4 :(得分:0)
/g
标志是&#34;全球匹配&#34; :匹配同一行中的模式多次。当您有三个管道时,带有两个管道的模式与两个第一个管道匹配,并且仅使用最后一个管道。如果您有四个连续的管道,那么您将匹配两个第一个管道,然后是最后两个管道:||||
变为| || |
。
/g
不是递归标志。您希望以||
递归替换| |
。要做到这一点,你需要使用标签和测试:来自@ 999999999999999999999999999999的答案是sed的好答案。
答案 5 :(得分:0)
sed 's/|/| /g;s/| \([^|]\)/|\1|/g' YourFile
在|
之后添加一个空格,删除|
之后没有|
的spave。通过这种方式,没有递归和每个管道被处理而不排除下一个。
Posix也兼容