在 Linux sed 中,如何用相同数量的不同字符实例替换某个字符的多个实例?

在 Linux sed 中,如何用相同数量的不同字符实例替换某个字符的多个实例?

我需要用精确数量的替换字符替换一组重复的字符(2 个或更多)。我需要使用 sed 或 vi 来执行此操作。

例子

"abc,,,def" becomes "abc|||dev"
"1245d,,,,,22" becomes "1245d|||||22"

谢谢

答案1

通过管道sed,像

echo "abc,,,def" | sed 's/,/|/g'

但我建议使用

tr ',' '|'

在这种情况下。

答案2

抱歉,我没有评论,因为我的声望没有 50 点。

如果存在更多模式,则此解决方案将会失败,例如abc,,,def,g

sed -n 's/[^,],,/&/;tsubs;p;d;:subs s/,/|/g;p' <<<'abc,,,def
abc,,def
abc,,,def,g
abc,def'

答案3

由于正则表达式的工作方式,这实际上是不可能的。正如 jvb 已经指出的那样,如果知道连续源字符的最大数量,解决方案就很简单(尽管不一定很短)。如果不知道,可以先更改所有源字符,然后在第二步中改回单个字符。但是,这仅在目标字符未出现在输入流中,或者您可以使用已知不会出现在输入流中的字符作为中间目标时才有效。

此外,你还需要考虑在行首或行末出现单个源字符的特殊情况。因此:

tr ',' '|' < file | sed 's/\([^|]\)|\([^|]\)/\1,\2/;s/^|\([^|]\)/,\1/;s/\([^|]\)|$/\1,/'

或者

sed 's/,/|/g;s/\([^|]\)|\([^|]\)/\1,\2/;s/^|\([^|]\)/,\1/;s/\([^|]\)|$/\1,/' file

使用具有字符串长度概念的语言的解决方案会更加健壮。

相关内容