2012-10-19 13 views
13

Kolejne pytanie dla ekspertów sed.Wyodrębnij liczby z ciągu za pomocą sed i wyrażeń regularnych

Mam ciąg reprezentujący ścieżkę, która będzie zawierać dwie liczby. Przykładem jest:

./pentaray_run2/Trace_220560.dat 

muszę wyodrębnić drugi z tych numerów - czyli 220560

mam (z niewielką pomocą forów) udało się wyodrębnić wszystkie numery razem (tzn 2220560) z :

sed "s/[^0-9]//g" 

lub wyodrębnić tylko pierwszy numer z:

sed -r 's|^([^.]+).*$|\1|; s|^[^0-9]*([0-9]+).*$|\1|' 

ale co jestem afte r jest drugą liczbą !! Każda pomoc doceniona.

PS numer, który widzę jest zawsze drugą liczbą w ciągu znaków.

Odpowiedz

12

czy to jest ok?

sed -r 's/.*_([0-9]*)\..*/\1/g' 

ze swoim przykładzie:

kent$ echo "./pentaray_run2/Trace_220560.dat"|sed -r 's/.*_([0-9]*)\..*/\1/g' 
220560 
+0

Świetne robią smakołyki. Domyślam się, że tam oznacza szukanie liczb tylko po podkreśleniu? W tym przypadku zawsze mogę oczekiwać podkreślenia, więc to zadziała. To, co jest faktycznym fragmentem wyrażenia, to znaczy. * _ Stackoverflow naprawdę jest tak fantastycznym zasobem - zastanawiałem się nad tym przez wiele godzin. Ciekawe, czy jest jakiś sposób na użycie \ 1 na końcu - może wyodrębnić wszystkie liczby (ciągłe cyfry) jako podłańcuchy i poprosić o drugi. Może to być przydatne dla mnie i innych osób w przyszłości? – Steven

6

Jeśli grep jest mile widziane:

$ echo './pentaray_run2/Trace_220560.dat' | grep -oP '\d+\D+\K\d+' 
220560 

I bardziej przenośne z Perl z tego samego regex:

echo './pentaray_run2/Trace_220560.dat' | perl -lne 'print $& if /\d+\D+\K\d+/' 
220560 

myślę podejście jest czystsze & bardziej wytrzymałe niż przy użyciu sed

6

Można wyodrębnić ostatnie cyfry z tym:

sed -e 's/.*[^0-9]\([0-9]\+\)[^0-9]*$/\1/' 

Łatwiej jest myśleć, że to do tyłu:

  1. Od końca łańcucha , mecz zero lub więcej znaków niż cyfra
  2. Mecz (wychwytywania i) jeden lub więcej znaków numerycznych
  3. Mecz na najmniej jeden non-cyfrowy charakter
  4. dopasować wszystkie znaki na początku łańcucha

Part 3 meczu, gdzie jest „magia” dzieje, ale również ogranicza wasze mecze mieć przynajmniej non -digit przed liczbą (np. nie można dopasować ciągu z tylko jedną liczbą, która jest na początku łańcucha, chociaż istnieje proste obejście wstawiania nie cyfry na początku łańcucha).

Magia polega na przeciwdziałaniu chciwości od lewej do prawej części .* (część 4). Bez części 3, część 4 zużywałaby wszystko, co może zawierać cyfry, ale dzięki temu dopasowywanie zapewnia zatrzymanie się, aby umożliwić użycie części nie będących cyframi, a następnie cyfry części 1 i 2, zezwalanie na przechwycenie numeru.

5

To może pracować dla Ciebie (GNU sed):

sed -r 's/([^0-9]*([0-9]*)){2}.*/\2/' file 

ten wyodrębnia numer drugie:

sed -r 's/([^0-9]*([0-9]*)){1}.*/\2/' file 

i wydobywa to pierwszy.

Powiązane problemy