2017-01-31 15 views
9

here से कुछ मदद के साथ, मेरे पास यह लगभग वैसे ही काम कर रहा है जिस तरह से मैं चाहता हूं। अब की तुलना करने से पहले मुझे फ़ाइल से डेटा को हटाने की क्षमता जोड़ने की आवश्यकता है।फ़ाइल डेटा को प्रतिस्थापित करने के लिए रेगेक्स का उपयोग

इसका कारण तार है, "डेटा", जिसे मैं हटा रहा हूं, फ़ाइल को सहेजने के हर बार भिन्न होने के लिए जाना जाता है।

मैंने सटीक पाठ का चयन करने के लिए एक रेगेक्स लिखा है जिसे मैं निकालना चाहता हूं, लेकिन मुझे अपने वर्तमान कोड के साथ इसे लागू करने में समस्या हो रही है।

यहाँ तीन मुख्य कार्य

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 

यह तार खोजने हटा दिया जाना चाहिए के लिए regex है कर रहे हैं।

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 
! 

मैं #filename = re.sub (REMOVE_RE, subst, फ़ाइल नाम की तरह कुछ कर रही कोशिश की है, 0, re.MULTILINE) get_file_info के भीतर और get_file_info_from_lines b क्योंकि मैं स्पष्ट रूप से इसे सही ढंग से कार्यान्वित नहीं कर रहा हूं।

किसी भी मदद की सराहना की जाएगी क्योंकि मैं बस सीख रहा हूं।

तुलना चल रहा है:

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() 

मैं वर्तमान फ़ाइल को संशोधित करने के लिए नहीं करना चाहती। अगर यह सब स्मृति में किया जा सकता है या अस्थायी फ़ाइल बहुत अच्छी होगी।

पूर्ण कोड:

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() 
+0

कोई मदद? मैं अभी भी इसे सही तरीके से काम करने में असमर्थ हूं। – NineTail

+0

क्या आप कृपया पूरा कोड जोड़ सकते हैं - ताकि हम जान सकें कि कौन सी libs का उपयोग किया जाता है? अपने कोड काम कर सकते हैं! क्षमा करें –

+0

@ एमडी। सैफतुल इस्लाम हो गया। – NineTail

उत्तर

0

मैं regex के चारों ओर एक रास्ता मिल पा रहा था की जाँच करने के। मैं लाइन से मेल करके लाइनों को हटा देता हूं।

def get_file_info_from_lines(filename, file_lines): 
    hostname = None 
    a_hash = hashlib.sha1() 
    for line in file_lines: 
     if "! Last " in line: 
      line = '' 
     if "! NVRAM " in line: 
      line = '' 
     a_hash.update(line.encode('utf-8')) 
     match = HOSTNAME_RE.match(line) 
     if match: 
      hostname = match.group(1) 
0

get_file_info_from_lines में, बस लाइन अगर यह आपका रेगुलर एक्सप्रेशन से मेल खाता है पर ध्यान न दें। इस तरह आपको वास्तव में फ़ाइल को संशोधित करने या किसी अन्य फ़ाइल को बनाने की आवश्यकता नहीं है, आप बस हेश की गणना उन पंक्तियों के साथ करते हैं जो वास्तव में मायने रखते हैं। एक लाइन साफ ​​करने के लिए एक समारोह उपयोग:

for line in file_lines: 
    if not re.match(REMOVE_RE, line): 
     a_hash.update(line.encode('utf-8')) 
+0

का उपयोग करने पर विचार करें जो ऐसा दिखता है काम लेकिन यह अभी भी कह रहा है कि एक अंतर है। दोनों फाइलें उस भाग को छोड़कर समान हैं जहां यह वर्तमान कॉन्फ़िगरेशन कहती है। मैं सिर्फ परीक्षण के लिए कुछ अक्षर जोड़ या हटा देता हूं। – NineTail

+0

अगर मैंने कुछ याद किया तो मैं बस एक त्वरित परीक्षण चला गया लेकिन यह ठीक काम कर रहा है। आपके कोड के साथ कुछ और गलत होना चाहिए। – lufte

+0

अच्छी तरह से, मेरा कोड आपके द्वारा किए गए परिवर्तन के साथ उपरोक्त जैसा ही है और यह अभी भी वापस लौट रहा है कि फाइलें अलग हैं। क्या आपने वर्तमान कॉन्फ़िगरेशन में लाइनें बदल दी हैं? कुछ और करने के लिए "उपयोगकर्ता द्वारा" परिवर्तन की तरह? सन 12 जनवरी 2017 उपयोगकर्ता 1234 द्वारा उदाहरण के लिए एक फ़ाइल में लेकिन दूसरा नहीं? – NineTail

0

हाय मैं आप निम्नलिखित apporach उपयोग करने के लिए सुझाव देते हैं। खाली लोगों को हटाने के लिए प्रक्रिया लाइनें।

फिर तुलना करने के लिए Difflib का उपयोग करें। उपयोग python -m doctest file.pydoctest

import re 
source_content = """ 
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 
! 
""" 

target_content = """ 
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 
! 
""" 



HOSTNAME_RE = re.compile(r'hostname +(\S+)') 
REMOVE_RE = re.compile(r"((?:\bCurrent configuration)(?:.*\n?){6})") 


def process_line(line): 
    """ 
    >>> process_line('! rgrg') 
    '!' 
    >>> process_line('username admin privilege 15 password 7 ***encrypted password***') 

    """ 

    if line.startswith('!'): 
     return '!' 
    if HOSTNAME_RE.match(line): 
     return match.group(1) 
    if REMOVE_RE.match(line): 
     return '' 
    return line 

#debug 
for line in source_content.split('\n'): 
    print(repr(process_line(line).strip())) 

whitened = '\n'.join(process_line(line).strip() 
        for line in source_content.split('\n')) 

def clean_lines(lines, flag=''): 
    """ Replaces multiple 'flag' lines by only one. 
    """ 
    res = [] 
    in_block = False 
    for line in lines: 

     if line.strip('\n') == flag: 
      if not in_block: 
       res.append(line) 
       in_block = True 
      continue 
     in_block = False 
     res.append(line) 
    return res 

print('^^^^^^^^^^^^^^') 
no_exc = '\n'.join(clean_lines(whitened.split('\n'), flag='!')) 
print(no_exc) 
print('##############') 
no_sp = '\n'.join(clean_lines(no_exc.split('\n')))   
print(no_sp) 
+0

यह सबसे नज़दीक है जिसे मैंने वास्तव में उन पंक्तियों को हटाने के लिए देखा है जिन्हें मैं शामिल नहीं करना चाहता हूं। ऐसा लगता है कि मुझे पूरे दृष्टिकोण को ड्राइंग बोर्ड पर वापस लेना पड़ सकता है। – NineTail

+0

कोई समस्या नहीं है। आपने आर्किटेक्चर में शुरुआती गलतियों को बनाया है। यह सबके साथ हुआ। इस वीडियो और उदाहरण कोड पर एक नज़र डालें: https://www.youtube.com/watch?v=DJtef410XaM मैंने अभी जो भी सलाह दी है उसे लागू किया :)। – cgte

संबंधित मुद्दे

 संबंधित मुद्दे