我试图提取下面给出的数字,但屏幕上没有任何内容:
echo "This is an example: 65 apples" | sed -n 's/.*\([0-9]*\) apples/\1/p'
然而,如果两个数字分别匹配,我得到'65',如下所示:
echo "This is an example: 65 apples" | sed -n 's/.*\([0-9][0-9]\) apples/\1/p'
65
如何匹配一个数字,以至于我不知道要提取的数字中的位数,例如可以用2344代替65?
答案 0 :(得分:18)
$ echo "This is an example: 65 apples" | sed -r 's/^[^0-9]*([0-9]+).*/\1/'
65
答案 1 :(得分:5)
这是因为您的第一个.*
贪婪,而您的[0-9]*
允许0位或更多位数。
因此,.*
尽可能地吞噬(包括数字),而[0-9]*
则不匹配。
你可以这样做:
echo "This is an example: 65 apples" | sed -n 's/.*\b\([0-9]\+\) apples/\1/p'
我迫使[0-9]
匹配至少一位数字,并在数字前添加了一个单词边界,以便匹配整数。
但是,使用grep
更容易,只需匹配数字:
echo "This is an example: 65 apples" | grep -P -o '[0-9]+(?= +apples)'
-P
表示“perl regex”(所以我不必担心转义'+')。
-o
表示“仅打印匹配项”。
(?= +apples)
表示匹配数字,后跟单词apples。
答案 2 :(得分:2)
你所看到的是正则表达式的贪婪行为。在您的第一个示例中,.*
吞噬了所有数字。这样的事情就是这样:
echo "This is an example: 65144 apples" | sed -n 's/[^0-9]*\([0-9]\+\) apples/\1/p'
65144
这样,您无法匹配第一位中的任何数字。一些正则表达式方言可以要求非贪婪匹配,但我不相信sed
有一个。
答案 3 :(得分:2)
从字符串中提取所有数字的简单方法
echo "1213 test 456 test 789" | grep -P -o "\d+"
结果:
1213
456
789
答案 4 :(得分:0)
echo "This is an example: 65 apples" | ssed -nR -e 's/.*?\b([0-9]*) apples/\1/p'
然而,你需要超级sed才能工作。 -R允许perl regexp。