我想获取最后两个数字(一个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'
如何只打印与组中的正则表达式匹配的行部分?
答案 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