我需要使用*
符号突出显示文本中的每个重复字词
例如
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
doesn't look behind if the match was found。
我可以仅使用sed
来处理它吗?
答案 0 :(得分:4)
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
答案 1 :(得分:1)
使用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*