2013-07-07 130 views
72

我想抓住最後兩個數字(一個int,一個float;後面是可選的空格)並僅打印它們。sed:只打印匹配組

例子:

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' 

我如何可以打印正則表達式的小組賽線路只有部分?

回答

80

匹配整行,所以在正則表達式的開頭添加.*。這將導致整行到與該組中的內容

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 
+24

我不得不添加'-r'或'--regexp-extended'選項,否則我在's'命令的RHS '錯誤處得到'invalid reference \ 1'。 –

+9

@DanielSokolowski我認爲如果你使用'('和')'而不是'\('和'\)',你會得到這個錯誤。 –

+1

還記得添加'。*'到正則表達式的末尾,如果要提取的字符串不總是在行的末尾。 –

45

的grep是用於提取合適的工具來代替。使用

你的榜樣,你的正則表達式:

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

@jozxyqk你的觀點是? – Kent

+6

非常適合整個組,但[sed需要個人組](http://superuser.com/questions/11130/can-gnu-grep-output-a-selected-group) – jozxyqk

+0

grep -o不能端口在運行msysgit但sed的系統上。 – cchamberlain

7

而對於另一種選擇,我會使用awk去!

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

這將在空間分割輸入(我在這裏使用STDIN,但你的輸入很容易被一個文件),然後打印出最後但-一個字段,然後最後一個字段。 $NF變量包含在空間上爆炸後找到的字段數。

這樣做的好處是,如果最後兩個字段前面的內容發生更改,只要您只希望最後兩個字段可以繼續工作,則無關緊要。

0

cut命令是爲這種確切的情況而設計的。它會在任何分隔符上「剪切」,然後你可以指定應該輸出哪些塊。

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

將導致輸出: 2 3.4

-d設置定界符

-f選擇'字段的輸出的範圍內,在這種情況下,它原始字符串的第6到第7個塊。