Fel
Fel

Reputation: 43

Python solution for reading a text file into an if statement

I am a new to Python and I am trying to parse some network data to figure out where a certain ip address is based on the city that it is in. I have the following code working below. But I have several hundred lines of information that I would like my script to go through and creating a specific if/else statement for each one didn't seem efficient.

from netaddr import *
def locateip(ipaddr):
    if IPAddress(ipaddr) in IPNetwork('10.10.10.0/24'):  
        return 'New York', '10', '10.10.10.0', '10.10.10.0/24', '255.255.255.0'
    elif IPAddress(ipaddr) in IPNetwork('10.10.20.0/24'):
        return 'Chicago', '20', '10.10.20.0', '10.10.20.0/24', '255.255.255.0'
    elif IPAddress(ipaddr) in IPNetwork('10.10.20.0/24'):
        return 'Dallas', '30', '10.10.30.0', '10.10.30.0/24', '255.255.255.0'
ipaddrsource = raw_input('Source Ip Address:')
try:
    srclocation, srcvlan, srcnetwork, srcnetworkcidr, srcsubnetmask = locateip(ipaddrsource)
except Exception, e:
    print e
print 'Location: ' + str(srclocation)
print 'Vlan: ' + str(srcvlan)
print 'Network: ' + str(srcnetwork)
print 'Network/CIDR: ' + str(srcnetworkcidr)
print 'Subnet Mask: ' + str(srcsubnetmask)

All my data is formatted into a text file similar to what is listed below.

location vlan network network+cidr subnetmask
New York 10 10.10.10.0 10.10.10.0/24 255.255.255.0
Chicago 20 10.10.20.0 10.10.20.0/24 255.255.255.0
Dallas 30 10.10.30.0 10.10.30.0/24 255.255.255.0

I have been trying to get the following to work, but I haven't been able to figure out how to send a line out of a text file into the if statement to return the rest of the metadata back. Any help would be great!

from netaddr import *
def locateip(ipaddr):
    f = open('networkinfo.txt','r')
    for line in f:
        networkdata = line.split()
        if IPAddress(ipaddr) in IPNetwork(networkdata[3]):   
            return networkdata[0], networkdata[1], networkdata[2], networkdata[3], networkdata[4]
ipaddrsource = raw_input('Source Ip Address:')
try:
    srclocation, srcvlan, srcnetwork, srcnetworkcidr, srcsubnetmask = locateip(ipaddrsource)
except Exception, e:
    print e
print 'Location: ' + str(srclocation)
print 'Vlan: ' + str(srcvlan)
print 'Network: ' + str(srcnetwork)
print 'Network/CIDR: ' + str(srcnetworkcidr)
print 'Subnet Mask: ' + str(srcsubnetmask)

Upvotes: 3

Views: 129

Answers (1)

Martijn Pieters
Martijn Pieters

Reputation: 1121486

Your lines start with a location, which itself can contain spaces. As such a straightforward str.split() won't work:

>>> 'New York 10 10.10.10.0 10.10.10.0/24 255.255.255.0\n'.split()
['New', 'York', '10', '10.10.10.0', '10.10.10.0/24', '255.255.255.0']

Note how New and York are two separate entries here, making networkdata[3] the wrong entry.

You need to split from the end, and limit the number of splits:

networkdata = line.rsplit(None, 4)

Demo:

>>> 'New York 10 10.10.10.0 10.10.10.0/24 255.255.255.0\n'.rsplit(None, 4)
['New York', '10', '10.10.10.0', '10.10.10.0/24', '255.255.255.0']

where None still splits on arbitrary-width whitespace and strips the newline from the end, but the 4 limits the splitting to 4 separators, leaving New York intact.

Or, as a complete method with some small improvements:

def locateip(ipaddr):
    ipaddr = IPAddress(ipaddress)
    with open('networkinfo.txt') as f:
        next(f, None)  # skip the header line first
        for line in f:
            location, vlan, net, netcdr, mask = line.rsplit(None, 4)
            if ipaddr in IPNetwork(netcdr):   
                return location, vlan, net, netcdr, mask

It could be that your input format is actually using tabs instead:

New York\t10\t10.10.10.0\t10.10.10.0/24\t255.255.255.0

in which case you probably want to read the format with the csv module instead:

import csv

def locateip(ipaddr):
    ipaddr = IPAddress(ipaddress)
    with open('networkinfo.txt') as f:
        reader = csv.reader(f, delimiter='\t')
        next(reader, None)  # skip the header line first
        for location, vlan, net, netcdr, mask in reader:
            if ipaddr in IPNetwork(netcdr):   
                return location, vlan, net, netcdr, mask

Upvotes: 4

Related Questions