Shell环境中正则表达式符号"?"失效问题求助
解决你的egrep匹配问题
首先得说清楚为啥你用egrep 't?' filename会返回所有行——这是因为t?的意思是「前面的t可以出现0次或者1次」,而任何文本都能满足这个条件:哪怕一行里完全没有t,它也能匹配空字符串,egrep默认只要行里有匹配就输出整行,所以自然会返回所有内容,这完全不是你想要的效果。
接下来看你的需求:从包含test best +see done++ feett ttesingt的文件里,得到best +see done++ vino+的输出。我猜你是想把那些包含多个t的单词(比如test、feett、ttesingt)要么过滤掉,要么替换成vino+?下面分两种情况给你解决方案:
情况1:只提取符合要求的单词(过滤掉多t的单词)
如果你只想保留那些t出现不超过1次的单词,用egrep加-o选项(只输出匹配到的部分),搭配这个正则:
egrep -o '\b(?!.*t.*t)[^[:space:]]+\b' filename
拆解一下这个正则:
\b:表示单词边界,确保我们匹配的是完整的单词,不会拆碎单词(?!.*t.*t):这是「负向前瞻」,意思是「排除那些包含至少两个t的单词」[^[:space:]]+:匹配一个或多个非空白字符,也就是单词本身
执行后会输出:
best +see done++
这和你的期望输出(除了vino+,应该是笔误)完全一致。
情况2:把多t的单词替换成vino+
如果你的真实需求是把原行里不符合要求的单词替换成vino+,那egrep就不够用了,得用sed来做替换:
sed -E 's/\b(.*t.*t[^[:space:]]*)\b/vino+/g' filename
解释一下:
s/.../.../g:全局替换模式,会把行里所有符合条件的内容都替换掉\b(.*t.*t[^[:space:]]*)\b:匹配包含至少两个t的完整单词vino+:替换成你指定的内容
执行这个命令后,输出就是你想要的:
vino+ best +see done++ vino+ vino+
补充提醒
如果你本来是想整行匹配(只输出完全符合要求的行),那需要明确行的规则,比如「行里所有单词的t都不超过1次」,但你的原行显然不符合这个条件,所以这种情况不会输出任何内容,应该不是你要的。
内容的提问来源于stack exchange,提问作者iamarunk
相关产品推荐
相关产品推荐

