1

I am trying to use Python Regex to get the IP address from the last line of a log.

I can get an IP if I search through the entire log. For example:

with open("read.log", "r+") as log:
    for line in log:
        address = "^\d{1,3}.\d{1,3}.\d{1,3}.\d{1,3}$"
        match = re.match(address, line)

But when I try to just read the last line and get an IP address, I do not get any results. How do I fix this?

import re

def run():

    try:
        logfile = open('read.log', 'r')
#       print ('First line in log: ',logfile.readline())

        for line in logfile:  
            x = line
            for ip in x:
                address = "^\d{1,3}.\d{1,3}.\d{1,3}.\d{1,3}$"
                match = re.match(address, ip)
                logfile.close   
        print ('Last Line: ', match)


    except OSError as e:
        print (e)

run()

My read.log looks like this...

10.1.177.198 Tue Jun 19 09:25:16 CDT 2018
10.1.160.198 Tue Jun 19 09:25:38 CDT 2018
10.1.177.198 Tue Jun 19 09:25:36 CDT 2018
10.1.177.198 Tue Jun 19 09:26:38 CDT 2018
10.1.177.198 Tue Jun 19 09:27:16 CDT 2018
10.1.177.198 Tue Jun 19 09:28:38 CDT 2018
LFB
  • 676
  • 2
  • 8
  • 20
Kade Williams
  • 1,041
  • 2
  • 13
  • 28
  • You closed `logfile` too early? (In the for-loop) – Geno Chen Jun 19 '18 at 16:58
  • 1
    `for ip in x` is iterating over the characters of the line. – Barmar Jun 19 '18 at 16:58
  • 1
    Maybe you meant to use `x = line.split()`? – Barmar Jun 19 '18 at 16:59
  • @Barmar Iterate in characters of lines is not necessary for you to do, which `re.match` has already done for you. – Geno Chen Jun 19 '18 at 17:00
  • Is the IP always the first field? Just use `ip = line.split()[0]` – Barmar Jun 19 '18 at 17:00
  • also regex for IP is wrong (no 1-255 constraint), unless you 100% sure that only IP in your logs have such format – aiven Jun 19 '18 at 17:02
  • @GenoChen But he's matching the regexp against the wrong thing. He needs to match it against the whole line, not one character at a time. – Barmar Jun 19 '18 at 17:02
  • Thanks, the split() fixed it. I can leave out Regex with ip = line.split()[0] – Kade Williams Jun 19 '18 at 17:04
  • @Barmar Yes, this is another fault. Using `.split()` to answer this question may mean this question is an X - Y question :-) – Geno Chen Jun 19 '18 at 17:05
  • This stuff is all incidental to the main question, which is about how to get the last line of the file. – Barmar Jun 19 '18 at 17:07
  • Possible duplicate of [Print Last Line of File Read In with Python](https://stackoverflow.com/questions/37227909/print-last-line-of-file-read-in-with-python) – Barmar Jun 19 '18 at 17:08
  • @Barmar I was already able to read the last line of the file. I was wanting to search for a string from within that last line. – Kade Williams Jun 19 '18 at 17:23
  • @KadeWilliams Where in your script do you read the last line of the file? You read the first line, then close the file. – Barmar Jun 19 '18 at 19:37
  • The first script should work. At the end of the loop, `match` will contain the match from the last line of the file. It's done lots of unnecessary work, matching every other line as well. Why don't you just use the technique in the duplicate question to get the last line right away? – Barmar Jun 19 '18 at 19:40

1 Answers1

1

The problem is your regex. ^ matches the beginning of a line, $ the end. If your log lines /only/ had the IP address, your code would work.

>>> import re
>>> m = re.compile("^\d{1,3}.\d{1,3}.\d{1,3}.\d{1,3}$")
>>> m.search('123.123.123.123')
<_sre.SRE_Match object; span=(0, 15), match='123.123.123.123'>

However, that's not the case. The following change will fix your search issue:

>>> import re
>>> m = re.compile("(^\d{1,3}.\d{1,3}.\d{1,3}.\d{1,3})\s")
>>> m.search('10.1.177.198 Tue Jun 19 09:28:38 CDT 2018').groups()[0]
>>> '10.1.177.198'
Demian Brecht
  • 21,135
  • 5
  • 42
  • 46