I’m doing comparison between 2 txt files and i want to add before the difference lines the name of interface which contains this line to be like below :.
First file contains :
!CfgFileCrc:f4fcebea !Software Version V800R021C00SPC100 !Last configuration was updated at 2022-04-07 10:16:05 UTC !Last configuration was saved at 2022-04-09 21:00:41 UTC !MKHash info-center filter-id bymodule-alias system hwSecurityRisk info-center loghost source LoopBack1 set service-mode forwarding-mode enhance interface GigabitEthernet4/0/14 shutdown interface GigabitEthernet4/0/15 negotiation auto undo shutdown interface GigabitEthernet4/0/16 negotiation auto undo shutdown
Second file contains :
!CfgFileCrc:f4fcebea !Software Version V800R021C00SPC100 !Last configuration was updated at 2022-04-07 10:16:05 UTC !Last configuration was saved at 2022-04-09 21:00:41 UTC !MKHash info-center filter-id bymodule-alias system hwSecurityRisk info-center loghost source LoopBack1 set service-mode forwarding-mode enhance interface GigabitEthernet4/0/14 shutdown interface GigabitEthernet4/0/15 negotiation auto description CEM-Smart-Care-PS undo shutdown interface GigabitEthernet4/0/16 negotiation auto description CEM-Smart-Care-PS undo shutdown
Code is as below :
def files(Devices): doc = open('C:/Users/Ahmed Shouaib/Desktop/Difference/test/10-4-2022/'+Devices+'.txt', 'r') dox = open('C:/Users/Ahmed Shouaib/Desktop/Difference/test/7-4-2022/'+Devices+'.txt', 'r') f1 = [x for x in doc.readlines()] f2 = [x for x in dox.readlines()] with open('C:/Users/Ahmed Shouaib/Desktop/Difference/test/result/' + Devices + '.txt', 'w') as new: GGG = ['CfgFileCrc', 'Last configuration was','MKHash' , 'username ftpuser password'] for line in f1: if line not in f2 and not any(x in line for x in GGG): new.write("+"+line + 'n') GGG = ['CfgFileCrc','Last configuration was','MKHash','username ftpuser password'] XX=1 for line in f2: if line not in f1 and not any(x in line for x in GGG): if ( XX == 1): new.write('-' * 80 + 'n'+ 'n') XX = 0 new.write("-"+line + 'n') doc.close() dox.close() files('10.0.130.71')
code result is like below :
+ description CEM-Smart-Care-PS + description CEM-Smart-Care-PS
The code result which i need to be :
interface GigabitEthernet4/0/15 + description CEM-Smart-Care-PS interface GigabitEthernet4/0/16 + description CEM-Smart-Care-PS
Advertisement
Answer
It’s not necessary to reimplement algorithm to find differences, you can use difflib.ndiff()
, just some preparation required. We need to pass to ndiff()
only lines which belongs to interface.
We can use generator function which returns interface name and all lines belongs to this interface:
def iter_interface(f): interface = "" lines = [] for line in f: if interface: if line.startswith(" "): lines.append(line.strip()) else: yield interface, lines interface = "" lines = [] if line.startswith("interface"): interface = line.rstrip() if interface: yield interface, lines
Then we just open both files and iterate over them using our generator function. If interface names are equal in both files we simply pass lines to ndiff()
and print only differences:
from difflib import ndiff ... with open("file1.txt") as f1, open("file2.txt") as f2: for (interface_f1, lines_f1), (interface_f2, lines_f2) in zip(iter_interface(f1), iter_interface(f2)): if interface_f1 == interface_f2: interface_printed = False for diff_line in ndiff(lines_f1, lines_f2): if diff_line[0] != " ": if not interface_printed: print(interface_f1) interface_printed = True print(diff_line) if interface_printed: print()
Using two file samples you provided you will get next output:
interface GigabitEthernet4/0/15 + description CEM-Smart-Care-PS interface GigabitEthernet4/0/16 + description CEM-Smart-Care-PS
P.S. Using generator function allows you to not keep entire file content in memory, so this method should work fine with large files.