2017-04-26 101 views
2

我在查找比较两个文件以创建第三个文件的有效方法时遇到了一些问题。将包含IP的两个文件与Python进行比较

我使用Python 3.6

第一个文件是IP地址的列表,我想删除。第二个文件包含与该目标为删除的IP地址相关联的所有DNS记录。

如果我在第二个文件中找到DNS记录,我想将整行添加到第三个文件。

这是文件1的样品:

IP 
10.10.10.234 
10.34.76.4 

这是文件2的样品:

DNS Record Type,DNS Record,DNS Response,View 
PTR,10.10.10.234,testing.example.com,internal 
A,testing.example.com,10.10.10.234,internal 
A,dns.google.com,8.8.8.8,external 

这就是我想要做的事。这是准确的,但它是永恒的。文件2中有〜200万行,文件1中有150K行。

def create_final_stale_ip_file(): 
    PD = set() 
    with open(stale_file) as f1: 
     reader1 = csv.DictReader(f1) 
     for row1 in reader1: 
      with open(prod_dns) as f2: 
       reader2 = csv.DictReader(f2) 
       for row2 in reader2: 
        if row2['DNS Record Type'] == 'A': 
         if row1['IP'] == row2['DNS Response']: 
          PD.update([row2['View']+'del,'+row2['DNS Record Type']+','+row2['DNS Record']+','+row2['DNS Response']]) 
        if row2['DNS Record Type'] == 'PTR': 
         if row1['IP'] == row2['DNS Record']: 
          PD.update([row2['View']+'del,'+row2['DNS Record Type']+','+row2['DNS Response']+','+row2['DNS Record']]) 


    o1 = open(delete_file,'a') 
    for i in PD: 
     o1.write(i+'\n') 
    o1.close() 

在此先感谢!

+0

没有通配符,网络掩码或子网,所以你不需要处理'10.34.76。*'或'10.34。*。*'每个IP地址都是一个文字字符串。 (为什么这个标签[标签:子网]?) – smci

+0

相关:[比较如果子网是在IP范围内,在Python?](http://stackoverflow.com/questions/22362894/compare-if-subnet-is-in -ip-range-in-python?rq = 1) – smci

回答

-1

可以使用grep很容易做到这一点:

grep -xf file1 file2 

这会给你的file2其匹配线file1该行的文件。从那里操作文本到你需要的最终形式应该更容易。

0

你应该阅读整个IP文件转换成set第一,然后检查是否在第二档的IP地址在该组中发现的,因为检查是否在一组存在一个元素是非常快:

def create_final_stale_ip_file(): 
    PD = set() 

    # It's much prettier and easier to manage the strings in one place 
    # and without using the + operator. Read about `str.format()` 
    # to understand how these work. They will be used later in the code 
    A_string = '{View}del,{DNS Record Type},{DNS Record},{DNS Response}' 
    PTR_string = '{View}del,{DNS Record Type},{DNS Response},{DNS Record}' 

    # We can open and create readers for both files at once 
    with open(stale_file) as f1, open(prod_dns) as f2: 
     reader1, reader2 = csv.DictReader(f1), csv.DictReader(f2) 

     # Read all IPs into a python set, they're fast! 
     ips = {row['IP'] for row in reader1} 

     # Now go through every line and simply check if the IP 
     # exists in the `ips` set we created above 
     for row in reader2: 
      if (row['DNS Record Type'] == 'A' 
        and row['DNS Response'] in ips): 
       PD.add(A_string.format(**row)) 
      elif (row['DNS Record Type'] == 'PTR' 
        and row2['DNS Record'] in ips): 
       PD.add(PTR_string.format(**row)) 

    # Finally, write all the lines to the file using `writelines()`. 
    # Also, it's always better to use `with open()` 
    with open(delete_file, 'a') as f: 
     f.writelines(PD) 

正如你看到的,我也改变了一些小东西,如:

  • 写入使用writelines()
  • 打开使用最后文件的文件安全
  • 我们只需要添加一个元素到我们设定的,所以使用PD.add()代替PD.update()
  • 使用Python的真棒str.format()创造更清洁的字符串格式化

最后但并非最不重要的,我真的将其分成多个函数,一个用于读取文件,一个用于读取字典等,每个函数都采用正确的参数,而不是像您似乎正在使用的全局变量名称,如stale_fileprod_dns。但这取决于你。

+0

非常高雅的使用[csv.DictReader](https://docs.python.org/2/library/csv.html#csv。DictReader) – smci

+0

你的意思是**行? ^^我喜欢字典用'.format()开箱'@smci –

+0

不,我的意思是全部。我没有使用DictReader,没有意识到它使事情变得如此干净。 – smci