我有一个用例,我想删除字符串中中间没有句点的每个单词。有人可以提供解决方案吗?如果愿意,请解释一下它是如何工作的?
字符串示例:
Testy.mctestface 1337 taco
期望的结果:
Testy.mctestface
答案1
使用grep
:
grep -oE '\w+\.\w+'
\w+
- 匹配任何单词字符(等于[a-zA-Z0-9_]
)
+
- 量词 — 匹配一次和无限次,尽可能多次,根据需要返回(贪婪)
\.
- 按字面匹配字符.
(区分大小写)
选项-o
表示grep
返回仅有的匹配时,该-E
选项允许扩展正则表达式。
这基本上会匹配包含句点的任何单词或单词组合。
$ echo 'foo bar Testy.mctestface 1337 taco' | grep -oE '\w+\.\w+'
Testy.mctestface
如果您的单词可以包含特殊字符,您可以使用以下内容:
grep -oE '\S+\.\S+'
将\S+
匹配任何非空白字符一次到无限次。
答案2
或许:
sed '
s/.*/ & /
:1
s/ [^ .]\{1,\} / /g
t1
s/^ //;s/ $//'
答案3
答案的一个稍微简单的版本awk
:
awk '{ for (i=1; i<=NF; i++) if ($i !~ /\./) $i = ""; print; }'
对于每个单词,如果不包含一个点,破坏它。然后打印剩下的内容。
重读这个问题时,我发现它说“每个单词......没有句点在中间其中”。因此,例如,输入
Mr. Smith ate .5 pies in New York.
不应该产生任何输出,因为没有单词有句点在中间。 相比之下,
Mr.Smith ate 1.5 pies in New York.
应报告Mr.Smith
并 1.5
.所以命令应该是
awk '{ for (i=1; i<=NF; i++) if ($i !~ /.\../) $i = ""; print; }'
对于每个单词,如果不包含一个句点,并且在其前后至少有一个其他字符,从而破坏该单词。
答案4
{
for(i=1; i <= NF; i++)
if ($i ~ /\./)
out=out" "$i
print out
out=""
}
...保存在文件中并通过 运行awk -f thatfile input1 input2...
,或者:
awk '{ for(i=1; i <= NF; i++) if ($i ~ /\./) out=out" "$i; print out; out="" }' input
...将脚本放在命令行上。
awk 根据空格(其特殊FS
变量的默认值)自动为您分割每一行输入。该脚本循环遍历该拆分的每个结果字段并运行测试:如果该字段的值包含句点(已转义,因为句点是正则表达式中的特殊标记),则将该字段(带有空格)附加到新的字段我们将在最后输出的字符串。这具有跳过不包含句点的字段的效果。一旦字段的循环完成,我们就打印重建的值(在 中out
)并将其重置为空字符串,以防输入中有更多行。