I'm trying to parse log file lines for IP addresses with grep -o '[0-9]{1,3}.[0-9]{1,3}.[0-9]{1,3}.[0-9]{1,3}' and would like to extract only last IP address in every given line.

Example of two lines to parse:

Via: SIP/2.0/UDP;branch=z9hG4bK-577783956;rport=5237
Via: SIP/2.0/UDP;branch=z9hG4bK-1014230957;rport=5079;received=

I'm getting:

What I would like to get:

I would appreciate your help.


You can try this sed

sed -E 's/.*[^0-9](([0-9]{1,3}\.){3}[0-9]{1,3}).*/\1/' infile

Explain :

-E to use extanded regular expression.
Without -E you must write the command this way

sed 's/.*[^0-9]\(\([0-9]\{1,3\}\.\)\{3\}[0-9]\{1,3\}\).*/\1/' infile

(([0-9]{1,3}.){3}[0-9]{1,3}) is the same RE as yours.

<-------> !  
    1     3 time



   1       2       3

The first part .*[^0-9] is greedy.
It match all it can before the last regex in the line.
The last .* match the end of the line.

  • We prefer answers that contain some explanation, and are not just a command. – G-Man Apr 26 '18 at 21:36

I like using awk in such cases:

$ awk '{print $NF}' FPAT="[0-9]{1,3}[.][0-9]{1,3}[.][0-9]{1,3}[.][0-9]{1,3}" file1

FPAT is used to define what a field consists of (identical to your grep -o pattern)
$NF is the last field of each line


Most regexp machinery use greedy patterns, i.e., they match as much as they can. So something like ^.*[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+ will match up to and including the last IPv4 address. Capture that.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.