2013-07-22 4 views
0

모든 서브넷과 IP 주소 범위가 겹치지 않도록 변경하는 CSV 파일을 만들려고했습니다. 원래의 질문은 여기에 Editing csv file to edit subnets so there is no overlap in IP ranges (ipaddress module in Python 3.3)입니다. 그러나 if 문이 ValueError을 멈추게하고 두 번째 문제가 실제로 문제가되지 않도록 수정했습니다. 이터레이터를 다시 설정할 수 있다면이 작업을 할 수 있다고 생각합니다. file1의 모든 행과 file2의 모든 행을 비교해야합니다. 난이 때반복자 오류 재설정

: 그것은 첫 번째 라인을 비교

import ipaddress 
import csv 
from csv import DictReader, DictWriter 

with open(r'file1.csv', newline='') as fin3,\ 
    open(r'file2.csv', newline='') as fin4,\ 
    open(r'file3.csv', 'w', newline='') as fout3: 


    read3 = DictReader(fin3) # fin 3 and 4 are copies of the same file 
    read4 = DictReader(fin4) 

    writenum3 = DictWriter(fout3, fieldnames=read3.fieldnames) 
    writenum3.writeheader() 

    for line3 in read3: 
     line3['Range']=ipaddress.ip_network(line3['Range']) # Convert IP ranges to ip network object 
     for line4 in read4: 
      line4['Range']=ipaddress.ip_network(line4['Range']) # Convert IP ranges to ip network object 
      if line3['Range'].netmask < line4['Range'].netmask: # To avoid "Not contained in" errors 
       if line3['Range'].overlaps(line4['Range']): # Tests for IP overlap 
        lst=list(line3['Range'].address_exclude(line4['Range'])) # List of subnets excluding line4 subnet 
        print (lst) # Temporary to view contents of lst 
        for val in lst: 
         line3['Range']=val # New range 
         line3[' IPStart']=val.network_address #New net address 
         line3[' IPStop']=val.broadcast_address #New broadcast address 
         writenum3.writerow(line3) # Write lines 

번째 라인 FILE1의 (헤더 생략) 파일 2의 (헤더 생략).

나는이 (file.seek(0) 사용) 한 :

import ipaddress 
import csv 
from csv import DictReader, DictWriter 

with open(r'file1.csv', newline='') as fin3,\ 
    open(r'file2.csv', newline='') as fin4,\ 
    open(r'file3.csv', 'w', newline='') as fout3: 


    read3 = DictReader(fin3) # fin 3 and 4 are copies of the same file 
    read4 = DictReader(fin4) 

    writenum3 = DictWriter(fout3, fieldnames=read3.fieldnames) 
    writenum3.writeheader() 

    for line3 in read3: 
     line3['Range']=ipaddress.ip_network(line3['Range']) # Convert IP ranges to ip network object 
     fin4.seek(0) 
     for line4 in read4: 
      line4['Range']=ipaddress.ip_network(line4['Range']) # Convert IP ranges to ip network object 
      if line3['Range'].netmask < line4['Range'].netmask: # To avoid "Not contained in" errors 
       if line3['Range'].overlaps(line4['Range']): # Tests for IP overlap 
        lst=list(line3['Range'].address_exclude(line4['Range'])) # List of subnets excluding line4 subnet 
        print (lst) # Temporary to view contents of lst 
        for val in lst: 
         line3['Range']=val # New range 
         line3[' IPStart']=val.network_address #New net address 
         line3[' IPStop']=val.broadcast_address #New broadcast address 
         writenum3.writerow(line3) # Write lines 

이 오류 ValueError: 'Range' does not appear to be an IPv4 or IPv6 network을 제공합니다. 나는 list() 방법을 시도하는 경우

는 (: Can iterators be reset in Python? 여기에서 설명) :

import ipaddress 
import csv 
from csv import DictReader, DictWriter 

with open(r'file1.csv', newline='') as fin3,\ 
    open(r'file2.csv', newline='') as fin4,\ 
    open(r'file3.csv', 'w', newline='') as fout3: 


    read3 = list(DictReader(fin3)) # fin 3 and 4 are copies of the same file 
    read4 = list(DictReader(fin4)) 

    writenum3 = DictWriter(fout3, fieldnames=read3.fieldnames) 
    writenum3.writeheader() 

    for line3 in read3: 
     line3['Range']=ipaddress.ip_network(line3['Range']) # Convert IP ranges to ip network object 
     fin4.seek(0) # Reset iterator 
     for line4 in read4: 
      line4['Range']=ipaddress.ip_network(line4['Range']) # Convert IP ranges to ip network object 
      if line3['Range'].netmask < line4['Range'].netmask: # To avoid "Not contained in" errors 
       if line3['Range'].overlaps(line4['Range']): # Tests for IP overlap 
        lst=list(line3['Range'].address_exclude(line4['Range'])) # List of subnets excluding line4 subnet 
        print (lst) # Temporary to view contents of lst 
        for val in lst: 
         line3['Range']=val # New range 
         line3[' IPStart']=val.network_address #New net address 
         line3[' IPStop']=val.broadcast_address #New broadcast address 
         writenum3.writerow(line3) # Write lines 

는 그것은 AttributeError: 'list' object has no attribute 'fieldnames' 오류가 있습니다.

여기에 http://docs.python.org/3.4/library/itertools.htmltee()을 사용해야하는지 궁금하지만 여기서는 사용법이나 작동 여부를 잘 모르겠습니다.

이 내 파일 1과 파일 2입니다 :

Zone Name, IPStart, IPStop,Range,Source 
Group A,10.0.0.0,10.127.255.255,10.0.0.0/9,New List 
Group A Sales,10.16.0.0,10.31.255.255,10.16.0.0/12,New List 
Group A Marketing,10.62.0.0,10.62.255.255,10.62.0.0/16,New List 
Group A Research,10.62.0.0,10.63.255.255,10.62.0.0/15,Old List 
Group A Sales Primary routers,10.23.1.0,10.23.1.15,10.24.1.0/28,New List 
Group A Sales Web Servers - Primary,10.18.0.0,10.18.0.255,10.18.0.0/24,New List 
Group A Sales Web Servers,10.16.0.0,10.19.255.255,10.16.0.0/14,New List 
Group B,10.128.0.0,10.255.255.255,10.128.0.0/9,Old List 

그리고 이것은 내가 궁극적으로 (각 서브넷의 모든 비교하지만 지금은 괜찮습니다) 원하는 것입니다 :

Zone Name, IPStart, IPStop,Range,Source 
Group A,10.0.0.0,10.15.255.255,10.0.0.0/12,New List 
Group A,10.32.0.0,10.47.255.255,10.32.0.0/12,New List 
Group A,10.48.0.0,10.55.255.255,10.48.0.0/13,New List 
Group A,10.56.0.0,10.59.255.255,10.56.0.0/14,New List 
Group A,10.60.0.0,10.61.255.255,10.60.0.0/15,New List 
Group A,10.64.0.0,10.127.255.255,10.64.0.0/10,New List 
Group A Marketing,10.62.0.0,10.62.255.255,10.62.0.0/16,New List 
Group A Research,10.63.0.0,10.63.255.255,10.63.0.0/16,Old List 
Group A Sales,10.20.0.0,10.21.255.255,10.20.0.0/15,New List 
Group A Sales,10.22.0.0,10.22.255.255,10.22.0.0/16,New List 
Group A Sales,10.23.0.0,10.23.0.255,10.23.0.0/24,New List 
Group A Sales,10.23.1.128,10.23.1.255,10.23.1.128/25,New List 
Group A Sales,10.23.1.16,10.23.1.31,10.23.1.16/28,New List 
Group A Sales,10.23.1.32,10.23.1.63,10.23.1.32/27,New List 
Group A Sales,10.23.1.64,10.23.1.127,10.23.1.64/26,New List 
Group A Sales,10.23.128.0,10.23.255.255,10.23.128.0/17,New List 
Group A Sales,10.23.16.0,10.23.31.255,10.23.16.0/20,New List 
Group A Sales,10.23.2.0,10.23.3.255,10.23.2.0/23,New List 
Group A Sales,10.23.32.0,10.23.63.255,10.23.32.0/19,New List 
Group A Sales,10.23.4.0,10.23.7.255,10.23.4.0/22,New List 
Group A Sales,10.23.64.0,10.23.127.255,10.23.64.0/18,New List 
Group A Sales,10.23.8.0,10.23.15.255,10.23.8.0/21,New List 
Group A Sales,10.24.0.0,10.31.255.255,10.24.0.0/13,New List 
Group A Sales,10.24.32.0,10.24.63.255,10.24.32.0/19,New List 
Group A Sales Primary routers,10.23.1.0,10.23.1.15,10.24.1.0/28,New List 
Group A Sales Web Servers,10.16.0.0,10.17.255.255,10.16.0.0/15,New List 
Group A Sales Web Servers,10.19.0.0,10.19.255.255,10.19.0.0/16,New List 
Group A Sales Web Servers,10.18.128.0,10.18.255.255,10.18.128.0/17,New List 
Group A Sales Web Servers,10.18.64.0,10.18.127.255,10.18.64.0/18,New List 
Group A Sales Web Servers,10.18.32.0,10.18.63.255,10.18.32.0/19,New List 
Group A Sales Web Servers,10.18.16.0,10.18.31.255,10.18.16.0/20,New List 
Group A Sales Web Servers,10.18.8.0,10.18.15.255,10.18.8.0/21,New List 
Group A Sales Web Servers,10.18.4.0,10.18.7.255,10.18.4.0/22,New List 
Group A Sales Web Servers,10.18.2.0,10.18.3.255,10.18.2.0/23,New List 
Group A Sales Web Servers,10.18.1.0,10.18.1.255,10.18.1.0/24,New List 
Group A Sales Web Servers - Primary,10.18.0.0,10.18.0.255,10.18.0.0/24,New List 
Group B,10.128.0.0,10.255.255.255,10.128.0.0/9,Old List 

어떤 도움이 이 일이 어떻게 이루어 지는지 알았습니다.

감사합니다, B0T

+0

코드에서 주석이'# 핀 3과 4는 같은 file'의 복사본입니다, 그러나 당신은'다른 contenst을 공급 말한다 file1.csv'와'file1.csv'를 사용합니다. 이것의 의미는 무엇입니까? – martineau

+0

@martineau 동일한 파일을 자신과 비교하는 방법에 대해 마음을 감쌀 수 없으며 csv dictreader/writer에 대한 좋은 예제를 찾을 수 없기 때문에 동일한 파일의 복사본을 사용했습니다. – CircuitB0T

답변

1

나는 그냥 DictReader 인스턴스가 다시 파일의 시작 부분에서 시작, 그래서도 두 번째 시도에서 fin4.seek(0) # Reset iteratorread4 = DictReader(fin4)를 삽입 할 필요가 있다고 생각합니다.

+0

와우, 이건 내 문제를 해결 한 것 같습니다. 나는 단지 이것에 대한 예상 출력을 확인하여 확인해야합니다. 감사! – CircuitB0T

+0

들으십시오.'DictReader()'에 파일을 넘긴 후에는 파일에 직접 접근하지 않기 때문에 직접적으로 무엇을하는지 조심해야한다. 일반적으로 동기화 상태를 유지하기가 어려울 수 있으므로 이와 같이 하드 리셋이 필요합니다. – martineau

0

DictReader/Writer를 하위 클래스로 만들려면 다음과 같은 다른 방법으로 클래스를 다시 설정해야합니다. DictReader를 들어

: DictWriter를 들어

f = open(filename, "rb") 
d = csv.DictReader(f, delimiter=",") 

f.seek(0) 
d.__init__(f, delimiter=",") 

:

f = open(filename, "rb+") 
d = csv.DictWriter(f, fieldnames=fields, delimiter=",") 

f.seek(0) 
f.truncate(0) 
d.__init__(f, fieldnames=fields, delimiter=",") 
d.writeheader() 
f.flush()