sed提取数字

13

我试图使用 sed 提取数字:

echo hgdfjg678gfdg kjg45nn | sed 's/.*\([0-9]\+\).*/\1/g'

但是结果是: 5 如何提取:678和45? 先行致谢!


关于 sed 的好文章在这里 - Stphane
4个回答

22
问题在于.*中的.将匹配数字和非数字,只要有一个未被消耗的数字可以匹配到[0-9],它就会一直匹配下去。因此,不要提取数字,只需删除非数字即可:
echo hgdfjg678gfdg kjg45nn | sed 's/[^0-9]//g'

甚至更多

echo hgdfjg678gfdg kjg45nn | tr -d -c 0-9

3
在sed中,可能希望用单个空格替换非数字字符,以保留数字的原始分组。 - glenn jackman
请注意,sed 's/[^0-9]//g' 不会剪切掉换行符(在过滤多行字符串时很重要),但是 tr -d -c 0-9 会。 - demmonico

9
你可以使用带有-o选项的grep来实现这一功能:
$ echo hgdfjg678gfdg kjg45nn | grep -E -o "[0-9]+"
678
45

3
或者使用 tr
$ echo hgdfjg678gfdg kjg45nn | tr -d [a-z]
678 45

你也可以使用 tr -d [:alpha:] 处理大写字母。 - Claudio Kuenzler

2

sed中的.*是贪婪的。据我所知,没有非贪婪选项。
(在这种情况下,您必须使用[^0-9]*进行非贪婪匹配。但这只能起作用一次,因此您将仅获得678而不包括45。)

如果您必须仅使用sed,那么很难获得结果。
我建议使用gnu的grep

$ echo hgdfjg678gfdg kjg45nn | grep -oP '\d+'
678
45

如果你真的想坚持使用sed,这将是众多可能答案之一。
$ echo hgdfjg678gfdg kjg45nn | \
sed -e 's/\([0-9^]\)\([^0-9]\)/\1\n\2/g' | \
sed -n 's/[^0-9]*\([0-9]\+\).*/\1/p’
678
45

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接