1

I have input file that contains:

19:04:01.631948 IP (tos 0xc0, ttl 1, id 0, offset 0, flags [none], proto UDP (17), length 48)
181.173.82.61.1985 > 250.66.33.195.1985: HSRPv0-hello 20: state=active group=72 addr=171.64.72.1 hellotime=2s holdtime=7s priority=120 auth="vlan72^@^@"
19:04:02.061482 IP (tos 0xc0, ttl 1, id 0, offset 0, flags [none], proto UDP (17), length 48)

181.173.82.60.1985 > 250.66.33.195.1985: HSRPv0-hello 20: state=standby group=72      addr=171.64.72.1 hellotime=2s holdtime=7s priority=100 auth="vlan72^@^@"
19:04:03.583896 IP (tos 0xc0, ttl 1, id 0, offset 0, flags [none], proto UDP (17), length 48)

181.173.82.61.1985 > 250.66.33.195.1985: HSRPv0-hello 20: state=active group=72  addr=171.64.72.1 hellotime=2s holdtime=7s priority=120 auth="vlan72^@^@"
19:04:04.005483 IP (tos 0xc0, ttl 1, id 0, offset 0, flags [none], proto UDP (17), length 48)
181.173.82.60.1985 > 250.66.33.195.1985: HSRPv0-hello 20: state=standby group=72 addr=171.64.72.1 hellotime=2s holdtime=7s priority=100 auth="vlan72^@^@"
19:04:05.511947 IP (tos 0xc0, ttl 1, id 0, offset 0, flags [none], proto UDP (17), length 48)
181.173.82.61.1985 > 250.66.33.195.1985: HSRPv0-hello 20: state=active group=72 addr=171.64.72.1 hellotime=2s holdtime=7s priority=120 auth="vlan72^@^@"
19:04:05.997361 IP (tos 0xc0, ttl 1, id 0, offset 0, flags [none], proto UDP (17), length 48)

181.173.82.60.1985 > 250.66.33.195.1985: HSRPv0-hello 20: state=standby group=72 addr=171.64.72.1 hellotime=2s holdtime=7s priority=100 auth="vlan72^@^@"
19:04:07.427876 IP (tos 0xc0, ttl 1, id 0, offset 0, flags [none], proto UDP (17), length 48)

181.173.82.61.1985 > 250.66.33.195.1985: HSRPv0-hello 20: state=active group=72 addr=171.64.72.1 hellotime=2s holdtime=7s priority=120 auth="vlan72^@^@"
19:04:07.925385 IP (tos 0xc0, ttl 1, id 0, offset 0, flags [none], proto UDP (17), length 48)

181.173.82.60.1985 > 250.66.33.195.1985: HSRPv0-hello 20: state=standby group=72 addr=171.64.72.1 hellotime=2s holdtime=7s priority=100 auth="vlan72^@^@"
19:04:09.403864 IP (tos 0xc0, ttl 1, id 0, offset 0, flags [none], proto UDP (17), length 48)

181.173.82.61.1985 > 250.66.33.195.1985: HSRPv0-hello 20: state=active group=72 addr=171.64.72.1 hellotime=2s holdtime=7s priority=120 auth="vlan72^@^@"
19:04:09.845241 IP (tos 0xc0, ttl 1, id 0, offset 0, flags [none], proto UDP (17), length 48)

181.173.82.60.1985 > 250.66.33.195.1985: HSRPv0-hello 20: state=standby group=72   addr=171.64.72.1 hellotime=2s holdtime=7s priority=100 auth="vlan72^@^@"
19:04:10.877531 IP (tos 0xc0, ttl 1, id 0, offset 0, flags [none], proto IGMP (2), length 28)

and I want the output be like this:

181.173.82.61
and other ips
(just senders IP (left IP))

I tried the following regular expression in grep:

grep -E -o '[1-9][0-9][0-9]?\.[1-9][0-9][0-9]?\.[0-9][0-9][0-9]?\.[0-9][0-9][0-9]?\.\s\>

To solve this problem I try to check IPs ehit this format:

(ip)(port)(space)(>)

and then sed and delete the > and port numbers but my regular expression dose not work.
I will appreciate any other ways such as awk or better regular expressions.

1

If all you want is the first IP of each line, you could do this:

grep '>' file.txt | gawk '{print $1}' | cut -d "." -f -4

Output on your example file:

181.173.82.61
181.173.82.60
181.173.82.61
181.173.82.60
181.173.82.61
181.173.82.60
181.173.82.61
181.173.82.60
181.173.82.61
181.173.82.60

Explanation:

  • grep '>' file.txt : print only those lines that contain the character >. In the file you have posted these are the lines that start with an IP.

    grep '>' file.txt | head -1
    181.173.82.61.1985 > 250.66.33.195.1985: HSRPv0-hello 20: state=active group=72 addr=171.64.72.1 hellotime=2s holdtime=7s priority=120 auth="vlan72^@^@"
    
  • gawk '{print $1}' : print the first field of each line.

      grep '>' file.txt | gawk '{print $1}' | head -1
      181.173.82.61.1985
    
  • cut -d "." -f -4 : use . as the field delimiter and print everything up to the 4th field. This removes the extra numbers from the IPs.

    grep '>' file.txt | gawk '{print $1}' | cut -d "." -f -4 | head -1
    181.173.82.61
    
1

Right now your regular expression is only looking for an IP in the format xxx.xxx.xxx.xxx, but IPs can be x.x.x.x and anything in between like xxx.xxx.x.xx (and in your example: xxx.xxx.xx.xx for the IP portion).

So that means, your regular expression needs to look more like:

'[1-9]{1,3}\.[0-9}{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,4} >'

That says "I want 1-9 anywhere from 1 to 3 in a row, followed by a '.', then 0-9 anywhere from 1-3 in a row", and so-forth. Works for me without ?, FWIW.

Since you are explicitly saying "space and >", you don't need to be overly fancy there.

  • im not agree with u.it get the ips.(ive tested that) and tnx for your help – Arash Apr 23 '13 at 16:49
  • and your regular expression return 173.82.61.1985 instead of 181.173.82.61.1985 and is not valid ip address – Arash Apr 23 '13 at 16:56
1

I am pretty sure it can done better than this, but if I copy your example to a testfile and remove the markup (the extra 4 spaces at the start), then this works:

>cat testfile | grep -E "[1-9]{1,3}\.[0-9}{1,3}\.[0-9]{1,3}\.[1-9]{1,3}" | cut -d. -f1-4

Output of just the grep filters down to:

181.173.82.61.1985 > 250.66.33.195.1985: HSRPv0-hello 20: state=active group=72 addr=171.64.72.1 hellotime=2s holdtime=7s priority=120 auth="vlan72^@^@"
181.173.82.60.1985 > 250.66.33.195.1985: HSRPv0-hello 20: state=standby group=72      addr=171.64.72.1 hellotime=2s holdtime=7s priority=100 auth="vlan72^@^@"
181.173.82.61.1985 > 250.66.33.195.1985: HSRPv0-hello 20: state=active group=72  addr=171.64.72.1 hellotime=2s holdtime=7s priority=120 auth="vlan72^@^@"
181.173.82.60.1985 > 250.66.33.195.1985: HSRPv0-hello 20: state=standby group=72 addr=171.64.72.1 hellotime=2s holdtime=7s priority=100 auth="vlan72^@^@"

Cut is than used to grab only the first four fields (-f for field, 1-4 for 1,2,3,4), using the dot as a -deliminator).

  • tnx but its also return some invalid results such as: 181.173.82.60 181.173.82.61 181.173.82.60 181.173.82.61 > 229 181.173.83.239 > 245 181.173.82.61 181.173.82.60 172.30.79.250 > 247 181.173.82.61 181.173.82.60 181.173.82.47 > 245 172.19.11.163 > 253 181.173.82.61 > 239` – Arash Apr 23 '13 at 16:48
  • 181.173.82.61 > 229 it means i just want ip not > 229 but your code have few errors and this is nice :) – Arash Apr 23 '13 at 16:48
1

Using your example file and a regex, I have come to this simpler solution:

perl -ne 'print "$1\n" if /^(.*)\.\d+ >/' test.txt

It prints every match before ".portnumber >"

0

I am rather surprised no one posted this extremely simple grep solution. I copied and pasted your sample text into a text file called, "ips.txt" and ran the following command:

grep -Eo "^([0-9]{1,3}\.){3}[^. ]*" ips.txt

The output I got was:

181.173.82.61
181.173.82.60
181.173.82.61
181.173.82.60
181.173.82.61
181.173.82.60
181.173.82.61
181.173.82.60
181.173.82.61
181.173.82.60

And if you want to see ALL the IP_ADDRs in the file, just omit the ^ at the beginning of the regex of the grep command. It will display all IPs in a list for you to further sift through as desired.

enter image description here

Which happens to be the exact same output as the accepted answer only without using so many pipes. So long as your file needing to be parsed contains the sender IP_ADDR at the start of the line, this command will do what you need.

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.