Regex sed:仅打印匹配组

Regex sed:仅打印匹配组,regex,sed,Regex,Sed,我想获取最后两个数字(一个int,一个float;后跟可选的空格),然后只打印它们 例如: foo bar <foo> bla 1 2 3.4 到目前为止,我有以下几点: sed -n 's/\([0-9][0-9]*[\ \t][0-9.]*[\ \t]*$\)/replacement/p' 会给我 foo bar <foo> bla 1 replacement 如何仅打印与组中正则表达式匹配的行的部分?匹配整行,因此在正则表达式的开头添加一个*。这将导致整个

我想获取最后两个数字(一个int,一个float;后跟可选的空格),然后只打印它们

例如:

foo bar <foo> bla 1 2 3.4
到目前为止,我有以下几点:

sed -n  's/\([0-9][0-9]*[\ \t][0-9.]*[\ \t]*$\)/replacement/p' 
会给我

foo bar <foo> bla 1 replacement

如何仅打印与组中正则表达式匹配的行的部分?

匹配整行,因此在正则表达式的开头添加一个
*
。这将导致整个行被组的内容替换

echo "foo bar <foo> bla 1 2 3.4" |
 sed -n  's/.*\([0-9][0-9]*[\ \t][0-9.]*[ \t]*$\)/\1/p'
2 3.4
echo“foo-bar bla 1 2 3.4”|
sed-n's/*\([0-9][0-9]*[\\t][0-9.]*[\t]*$\)/\1/p'
2 3.4

grep是正确的提取工具

使用您的示例和正则表达式:

kent$  echo 'foo bar <foo> bla 1 2 3.4'|grep -o '[0-9][0-9]*[\ \t][0-9.]*[\ \t]*$'
2 3.4
kent$echo'foo bar bla 1 2 3.4'| grep-o'[0-9][0-9]*[\\t][0-9.]*[\\t]*$'
2 3.4

还有一个选择,我会选择awk

echo "foo bar <foo> bla 1 2 3.4" | awk '{ print $(NF-1), $NF; }'
echo“foo-bar bla 1 2 3.4”| awk'{print$(NF-1),$NF;}”
这将在空格上拆分输入(我在这里使用STDIN,但您的输入可能很容易成为文件),然后打印出最后一个字段,然后打印出最后一个字段。
$NF
变量保存在空格上分解后找到的字段数


这样做的好处是,如果最后两个字段前面的内容发生更改,则无关紧要,只要您只希望最后两个字段继续工作。

剪切命令就是针对这种情况设计的。它将“剪切”任何分隔符,然后您可以指定应该输出哪些块

例如:
echo“foo-bar bla 1 2 3.4”| cut-d”“-f 6-7

将产生以下输出:
23.4

-d设置分隔符

-f选择要输出的“字段”范围,在本例中,它是原始字符串的第6到第7个块。您还可以将范围指定为列表,例如
6,7

我同意这非常适合
grep-o
。如果您需要提取模式中的组,可以使用第二个grep

#从/xx([0-9]+)yy中提取\1/
$echo“aa678bb xx123yy xx4yy aa42 aa9bb”| grep-Eo'xx[0-9]+yy'| grep-Eo'[0-9]+'
123
4.
#从/a([0-9]+)b中提取\1的步骤/
$echo“aa678bb xx123yy xx4yy aa42 aa9bb”| grep-Eo'a[0-9]+b'| grep-Eo'[0-9]+'
678
9


当我看到两个对grep/sed/awk的调用同时进行时,我通常会感到畏缩,但这并不总是错的。虽然我们应该有效地锻炼做事的技巧,“愚蠢的一致性是小头脑的妖怪”和“真正的艺术家”。如果要提取的字符串不总是在行的末尾,请记住将
*
添加到regexp的末尾。这对我不起作用,因为
*
是贪婪的,sed没有非贪婪的
*?
@DanielDarabos只要提到
在ubuntu 16.04中不会引发错误。所以我认为这个评论已经过时了。这对整个团队来说都很好,尽管grep-o没有在运行msysgit的系统上进行移植,但是sed可以。请参阅@jozxyqk链接的问题,以获得一个答案,该答案使用“向前看”和“向后看”来解决这个问题。您可以通过管道
grep-o
调用从模式中提取一个组。注意:对于更复杂的正则表达式,您需要使用'grep-Eo'只打印某些列,管道到
awk'{print$2”“$6}“
@nurettin我想你的评论可能是针对awk的一个答案。我在访问此页面时尝试了剪切,并意识到它的局限性,决定用awk编写一个更通用的版本,以提高此帖子的质量。是的,我认为这属于涉及awk的不同答案。你写的剪切命令是:
cut-d”“-f2,6
啊,我不知道,我以为你只能给出范围。谢谢。这个问题要求的不仅仅是印刷。具有适当权限的人员应修改此问题。例如,您添加了允许更复杂正则表达式的
-E
标志
kent$  echo 'foo bar <foo> bla 1 2 3.4'|grep -o '[0-9][0-9]*[\ \t][0-9.]*[\ \t]*$'
2 3.4
echo "foo bar <foo> bla 1 2 3.4" | awk '{ print $(NF-1), $NF; }'