用sed多次在同一行执行命令

我需要使用*符号突出显示文本中的每个重复单词。
例如

 lol foo lol bar foo bar 

应该

 lol foo *lol* bar *foo* *bar* 

我试着用下面的命令:

 echo "lol foo lol bar foo bar" | sed -r -e 's/(\b[a-zA-Z]+\b)([^*]+)(\1)/\1\2*\3*/' 

它给了我:

 lol foo *lol* bar foo bar 

然后我加了g标志:

 lol foo *lol* bar foo *bar* 

foo没有突出显示。
我知道这是因为sed 没有find后面的匹配 。

我可以只sed处理吗?

Sed不是这个任务的最佳工具。 它不是先行的,后面的和非贪婪的量词,但试试看下面的命令:

 sed -r -e ':a ; s/\b([a-zA-Z]+)\b(.*) (\1)( |$)/\1\2 *\3* / ; ta' 

它使用条件分支来执行替代命令,直到它失败。 此外,你不能检查([^*]+)因为第二轮它必须遍历第一个替换的一些* ,你的选择是贪婪。 最后,你不能匹配(\1)因为它会一次又一次地匹配第一个字符串lol 。 你需要一些像空格或行尾一样的环境。

该命令产生:

 lol foo *lol* bar *foo* *bar* 

更新 : potong在评论中提供的改进:

 sed -r ':a;s/\b(([[:alpha:]]+)\s.*\s)\2\b/\1*\2*/;ta' file 

使用awk

 awk '{for (i=1;i<=NF;i++) if (a[$i]++>=1) printf "*%s* ",$i; else printf "%s ",$i; print ""}' file lol foo *lol* bar *foo* *bar*