sed:仅打印匹配组

时间:2013-07-07 11:14:32

标签: regex sed

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

示例:

foo bar <foo> bla 1 2 3.4

应打印:

2 3.4

到目前为止,我有以下内容:

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

会给我

foo bar <foo> bla 1 replacement

但是,如果我尝试将其替换为组1,则会打印整行。

sed -n  's/\([0-9][0-9]*[\ \t][0-9.]*[\ \t]*$\)/\1/p' 

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

5 个答案:

答案 0 :(得分:114)

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

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

答案 1 :(得分:60)

grep 是提取的正确工具。

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

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

答案 2 :(得分:9)

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

echo "foo bar <foo> bla 1 2 3.4" | awk '{ print $(NF-1), $NF; }'

这会在空格上分割输入(我在这里使用STDIN,但输入很容易就是文件),然后打印出最后一个字段,然后打印最后一个字段。 $NF变量包含在空格爆炸后找到的字段数。

这样做的好处是,如果最后两个字段之前的内容发生变化并不重要,只要您只想要最后两个字段就会继续工作。

答案 3 :(得分:3)

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

例如: echo "foo bar <foo> bla 1 2 3.4" | cut -d " " -f 6-7

将导致输出: 2 3.4

-d设置分隔符

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

答案 4 :(得分:0)

我同意@kent的观点,它非常适合grep -o。如果您需要提取模式中的组,则可以使用第二个grep来完成。

# To extract \1 from /xx([0-9]+)yy/
$ echo "aa678bb xx123yy xx4yy aa42 aa9bb" | grep -Eo 'xx[0-9]+yy' | grep -Eo '[0-9]+'
123
4

# To extract \1 from /a([0-9]+)b/
$ echo "aa678bb xx123yy xx4yy aa42 aa9bb" | grep -Eo 'a[0-9]+b' | grep -Eo '[0-9]+'
678
9