2013-07-07 13 views
72

Chcę pobrać dwie ostatnie liczby (jedną int, jedną zmienną, a następnie opcjonalną białą) i wydrukować tylko te.sed: drukuj tylko pasującą grupę

Przykład:

foo bar <foo> bla 1 2 3.4 

powinien wydrukować:

2 3.4 

tej pory mam następujące:

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

da mi

foo bar <foo> bla 1 replacement 

Jeśli jednak spróbuję zastąpić go grupą 1, drukowana jest cała linia.

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

Jak mogę wydrukować tylko część linii, która pasuje do wyrażenia regularnego w grupie?

Odpowiedz

80

Dopasuj całą linię, więc dodaj .* na początku wyrażeń regularnych. Powoduje to, że cała linia być zastąpione zawartością grupy

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

Musiałem dodać opcję '-r' lub' --regexp-extended' w przeciwnym razie otrzymywałem 'nieprawidłowe odwołanie \ 1 na komendzie' s 'polecenia RHS 'error. –

+9

@DanielSokolowski Myślę, że otrzymujesz ten błąd, jeśli używasz '(' i ')' zamiast '\ (' i '\)'. –

+1

Pamiętaj też, aby dodać '.* 'na końcu wyrażeń regularnych, jeśli ciąg, który chcesz wyodrębnić, nie zawsze znajduje się na końcu wiersza. –

45

grep jest właściwym narzędziem do ekstrakcji.

za pomocą przykładu i Twojego regex:

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 Twoim celem jest? – Kent

+6

idealne dla całej grupy, chociaż [sed jest potrzebny dla poszczególnych grup] (http://superuser.com/questions/11130/can-gnu-grep-output-a-selected-group) – jozxyqk

+0

grep -o nie portuje na systemach z uruchomionym programem msysgit, ale sed działa. – cchamberlain

7

A dla jeszcze innej opcji, pójdę z awk!

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

ten zostanie podzielony wejście (używam STDIN tutaj, ale Twój wkład może łatwo być plik) na przestrzeni, a następnie wydrukować przedostatnim jednym polu, a następnie ostatnie pole. Zmienne $NF zawierają liczbę pól znalezionych po eksplozji w przestrzeniach.

Zaletą tego jest to, że nie ma znaczenia, czy to, co poprzedza ostatnie dwie zmiany pól, tak długo, jak tylko chcesz dwóch ostatnich, to nadal będzie działać.

0

Polecenie przycięcia zostało zaprojektowane dla tej dokładnej sytuacji. Spowoduje to "wycięcie" na dowolnym ograniczniku, a następnie możesz określić, które fragmenty powinny zostać wyprowadzone.

Na przykład: echo "foo bar <foo> bla 1 2 3.4" | cut -d " " -f 6-7

spowoduje wyjście: 2 3.4

-d ustawia separator

-f wybiera zakres pojęcia 'pola' do wyjścia, w tym przypadku jest to 6 do 7 fragmentów oryginalnego napisu.