使用SED进行正则表达式替换的重复操作

5

我有以下行(实际上有约1M个这些行):

foo|||bar
qux||boo|fzx

请注意,每一行都恰好包含4个字段,但字符数可以超过3个。

我想做的是将每个||替换为|nil|,结果如下:

foo|nil|nil|bar
qux|nil|boo|fzx

如何使用sed命令实现此操作?

我尝试了以下方法但失败了:

sed 's/||/|nil/g'
1个回答

18

你需要重复替换直到它不再改变:

sed ':a; s/||/|nil|/g; ta'

然而,这并不能处理开头或结尾的空字段,因此您需要两个额外的模式:

sed 's/^|/nil|/; s/|$/|nil/; :a; s/||/|nil|/g; ta'

测试

cat << EOF > infile
foo|||bar
qux||boo|fzx
|||
EOF

运行它:

<infile sed 's/^|/nil|/; s/|$/|nil/; :a; s/||/|nil|/g; ta'

输出:

foo|nil|nil|bar
qux|nil|boo|fzx
nil|nil|nil|nil

一个awk方式

awk '{ for(i=1;i<=NF;i++) if(length($i)==0) $i="nil" } 1' FS='|' OFS='|'

在 OS X 上不能正常工作。您需要将每个部分拆分为新命令,如 tore 在此处描述:https://dev59.com/sGkw5IYBdhLWcg3wUI1W。在此示例中,请使用 sed -e ':a' -e 's/||/|nil|/g' -e 'ta'。 - Samuel

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接