Skip to content
Advertisement

Get a specific line before specific line in txt file after comparison

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.

Advertisement