Z pewną pomocą z here, mam to działa prawie dokładnie tak, jak chcę. Teraz muszę mieć możliwość dodania możliwości usuwania danych z pliku , zanim pliki zostaną porównane..Używanie regex do zastępowania danych pliku
Powodem tego są ciągi znaków, "dane", które usuwam, różnią się za każdym razem, gdy plik jest zapisywany.
Napisałem wyrażenie regularne, aby wybrać dokładny tekst, który chcę usunąć, ale mam problemy z zaimplementowaniem go przy użyciu mojego obecnego kodu.
Oto trzy główne funkcje
HOSTNAME_RE = re.compile(r'hostname +(\S+)')
def get_file_info_from_lines(filename, file_lines):
hostname = None
a_hash = hashlib.sha1()
for line in file_lines:
a_hash.update(line.encode('utf-8'))
match = HOSTNAME_RE.match(line)
if match:
hostname = match.group(1)
return hostname, filename, a_hash.hexdigest()
def get_file_info(filename):
if filename.endswith(('.cfg', '.startup', '.confg')):
with open(filename, "r+") as in_file:
#filename = re.sub(REMOVE_RE, subst, filename, 0, re.MULTILINE)
return get_file_info_from_lines(filename, in_file.readlines())
def hostname_parse(directory):
results = {}
i = 0
l = len(os.listdir(directory))
for filename in os.listdir(directory):
filename = os.path.join(directory, filename)
sleep(0.001)
i += 1
progress_bar(i, l, prefix = 'Progress:', suffix = 'Complete', barLength = 50)
info = get_file_info(filename)
if info is not None:
results[info[0]] = info
return results
to jest regex do znalezienia sznurki należy usunąć.
REMOVE_RE = r"((?:\bCurrent configuration)(?:.*\n?){6})"
subst = ""
EXAMPLE_FILE_BEFORE_DATA_REMOVED:
Building configuration...
Current configuration : 45617 bytes
!
! Last configuration change at 00:22:36 UTC Sun Jan 22 2017 by user
! NVRAM config last updated at 00:22:43 UTC Sun Jan 22 2017 by user
!
version 15.0
no service pad
!
no logging console
enable secret 5 ***encrypted password***
!
username admin privilege 15 password 7 ***encrypted password***
username sadmin privilege 15 secret 5 ***encrypted password***
aaa new-model
!
ip ftp username ***encrypted password***
ip ftp password 7 ***encrypted password***
ip ssh version 2
!
line con 0
password 7 ***encrypted password***
login authentication maint
line vty 0 4
password 7 ***encrypted password***
length 0
transport input ssh
line vty 5 15
password 7 ***encrypted password***
transport input ssh
!
EXAMPLE_FILE_AFTER_DATA_REMOVED:
Building configuration...
!
no service pad
!
no logging console
enable
!
username admin privilege 15
username gisadmin privilege 15
aaa new-model
!
ip ftp username cfgftp
ip ftp
ip ssh version 2
!
line con 0
login authentication maint
line vty 0 4
length 0
transport input ssh
line vty 5 15
transport input ssh
!
Próbowałem robić coś podobnego #filename = re.sub (REMOVE_RE, subst, nazwy pliku, 0, re.MULTILINE) w obrębie get_file_info i get_file_info_from_lines b ut Oczywiście nie wdrażam go poprawnie.
Każda pomoc będzie doceniona, ponieważ dopiero się uczę.
uruchamiając Porównaj:
results1 = hostname_parse('test1.txt')
results2 = hostname_parse('test2.txt')
for hostname, filename, filehash in results1.values():
if hostname in results2:
_, filename2, filehash2 = results2[hostname]
if filehash != filehash2:
print("%s has a change (%s, %s)" % (
hostname, filehash, filehash2))
print(filename)
print(filename2)
print()
Nie chcę, aby zmodyfikować bieżący plik. Jeśli wszystko to można zrobić w pamięci lub plik tymczasowy byłby świetny.
pełny kod:
import hashlib
import os
import re
HOSTNAME_RE = re.compile(r'hostname +(\S+)')
REMOVE_RE = re.compile(r"((?:\bCurrent configuration)(?:.*\n?){6})")
def get_file_info_from_lines(filename, file_lines):
hostname = None
a_hash = hashlib.sha1()
for line in file_lines:
#match = HOSTNAME_RE.match(line)
if not re.match(REMOVE_RE, line):
a_hash.update(line.encode('utf-8'))
#=======================================================================
# if match:
# hostname = match.group(1)
#=======================================================================
return hostname, filename, a_hash.hexdigest()
def get_file_info(filename):
if filename.endswith(('.cfg', '.startup', '.confg')):
with open(filename, "r+") as in_file:
return get_file_info_from_lines(filename, in_file.readlines())
def hostname_parse(directory):
results = {}
for filename in os.listdir(directory):
filename = os.path.join(directory, filename)
info = get_file_info(filename)
if info is not None:
results[info[0]] = info
return results
results1 = hostname_parse('test1') #Directory of test files
results2 = hostname_parse('test2') #Directory of test files 2
for hostname, filename, filehash in results1.values():
if hostname in results2:
_, filename2, filehash2 = results2[hostname]
if filehash != filehash2:
print("%s has a change (%s, %s)" % (
hostname, filehash, filehash2))
print(filename)
print(filename2)
print()
Każda pomoc? Nadal nie jestem w stanie sprawić, żeby to działało poprawnie. – NineTail
Czy możesz dodać pełny kod, abyśmy wiedzieli, które biblioteki są tu używane? Nie zezwalaj na pracę Twojego kodu! Przepraszam –
@ Md.SifatulIslam Zrobione. – NineTail