【问题标题】:How to search a specific word in child line. if match is found return parent and child line如何在子行中搜索特定单词。如果找到匹配,则返回父子行
【发布时间】:2021-07-02 06:10:16
【问题描述】:

在下面的数据中找到“10.10.10.1”,如果找到匹配项,则返回其父行“ip access-list extended test2”和匹配行“permit ip host 10.10.10.1 any log”

输入: 数据列表=

ip access-list extended test2 10.10.10.1
ip access-list extended test1
 deny   tcp any eq tacacs any
 permit ip any any
ip access-list extended test2
 permit ip any any
 permit ip host 10.10.10.1 any log
 permit icmp host 10.10.10.1 any
 permit tcp any any eq 22
 permit tcp any any eq tacacs
 permit tcp any any
 permit udp any any
ip access-list extended test3
 permit udp any any eq 123 log
 permit udp any any eq 1234 log
 permit ip any any

输出应该是:

ip access-list extended test2
 permit ip host 10.10.10.1 any log

这是我尝试过的,但我只能返回匹配行我不知道如何匹配父行

final_list = []
    for LINE in data_list:
    if re.search(r'\b{}\b'.format('10.10.10.1'), LINE):
        final_list.append(LINE)
    print(final_list)

【问题讨论】:

  • 如何识别父母?有缩进吗?
  • 您能否也添加您目前尝试过的代码/sn-ps,以及您面临的问题(如果有)?
  • 它必须识别子行上方的哪一行在行首没有空格或制表符。
  • 我添加了到目前为止我尝试过的内容,但它只返回匹配的行。我不知道如何将其父行置于子行之上。
  • 如果行首没有空格,则可以识别父行。如果开头有空格,则都是父行的子行

标签: python python-3.x regex


【解决方案1】:

据我所知,假设parent line 是指以ip access-list 开头的行,我们可以不使用正则表达式。

parent_line = None

# data being the input string
for line in data.splitlines():
    if line.startswith('ip access-list'):
        parent_line = line
    elif '10.10.10.1' in line:
        print(parent_line)
        print(line)

打印出来:

ip access-list extended test2
permit ip host 10.10.10.1 any log

如果需要根据开头的空格来识别父行和子行,则此代码将需要非常小的更改。

【讨论】:

    【解决方案2】:
    import re
    reg = r' .*10\.10\.10\.1.*'
    data = """
    ip access-list extended test1
     deny   tcp any eq tacacs any
     permit ip any any
    ip access-list extended test2
     permit ip any any
     permit ip host 10.10.10.1 any log
     permit icmp host 10.10.10.2 any
     permit tcp any any eq 22
     permit tcp any any eq tacacs
     permit tcp any any
     permit udp any any
    ip access-list extended test3
     permit udp any any eq 123 log
     permit udp any any eq 1234 log
     permit ip any any
    """ #read your data your way (open(file) or args)
    dataLines = data.split('\n')
    while '' in dataLines:
        dataLines.remove('')
    print(dataLines)
    parent = ''
    
    for i in dataLines:
        if not i[0] == ' ':
            parent = i
            continue
        else:
            if re.match(reg, i):
                print('\n'+parent)
                print(i)
                break
    

    这可能会有所帮助...

    【讨论】:

    • * 这假设您的父行不以空格开头,而您的子行始终以空格开头...
    • 是的..这对我有用..感谢您的帮助..
    【解决方案3】:

    我建议将data_list 字符串重新分组到单独的单独列表中,然后检查匹配项并在满足条件后获取结果。

    this Python demo:

    import re
    data = """ip access-list extended test1
     deny   tcp any eq tacacs any
     permit ip any any
    ip access-list extended test2
     permit ip any any
     permit ip host 10.10.10.1 any log
     permit icmp host 10.10.10.2 any
     permit tcp any any eq 22
     permit tcp any any eq tacacs
     permit tcp any any
     permit udp any any
    ip access-list extended test3
     permit udp any any eq 123 log
     permit udp any any eq 1234 log
     permit ip any any"""
    
    data_list = data.splitlines()
    data_ll = []
    search_key = '10.10.10.1'
    tmp = []
    for line in data_list:
        if line and not line[0].isspace():
            if tmp:
                m = re.search(fr".*\b{re.escape(search_key)}\b.*", "\n".join(tmp))
                if m:
                    data_ll.append([tmp[0], m.group()])
                tmp = [line.rstrip()]
            else:
                tmp.append(line.rstrip())
        elif line and line[0].isspace():
            tmp.append(line.rstrip())
    
    print(data_ll)
    

    输出:

    [['ip access-list extended test2', ' permit ip host 10.10.10.1 any log']]
    

    我还从search_key 变量初始化正则表达式,这就是为什么我使用re.escape(search_key) 来转义. 字符,否则它们匹配除换行符以外的任何字符。

    【讨论】:

    • 这很好用,但它不会在一个组中返回多个匹配的子行。
    • @razz 你希望得到什么?
    • 我希望所有匹配的子行都低于父行,但在这里我每父行只有一个子行,尽管它有多个匹配的子行。此外,如果父行具有匹配的 key_word,但在输出中确实有子行,则其复制的父行作为子行,但在这种情况下,我只期望匹配父行,因为它没有子行示例输出:``` [ ['ip access-list extended test2 10.10.10.1'], ['ip access-list extended test2', ' permit ip host 10.10.10.1 any log', ' permit icmp host 10.10.10.1 any']] ``
    • @razz 我不明白你的意思。 Here,您将列表中的整个块作为返回值。
    • 我用其他方式解决了 cisco config.. 在下面添加我的解决方案
    【解决方案4】:

    我已将设备配置存储在 device_config.cfg 文件中。使用 ciscoconfparse 和 regex 模块我可以做到这一点。

    from ciscoconfparse import CiscoConfParse
    import re
    
    
    final_list = []
    cisco_file = 'device_config.cfg'
    
    cisco_cfg = CiscoConfParse(cisco_file)
    parent_child_line = cisco_cfg.find_objects_w_child(parentspec=r"", childspec=r"10.10.10.10")
    parsed_data = cisco_cfg.find_objects(r"10.10.10.10")
    
    # print(parent_child_line)
    # print(parsed_data)
    
    for p_line in parent_child_line:
        # print(p_line.text)
        final_list.append(p_line.text)
        for child in p_line.children:
            if re.search(r'10.10.10.10', child.text):
                # print(child.text)
                final_list.append(child.text)
    
    print('\n#############################################\n')
    
    for i in parsed_data:
        if not re.search(r'^\s\w', i.text):
            # print(i.text)
            final_list.append(i.text)
            print(final_list)
    

    【讨论】:

      猜你喜欢
      • 2018-04-15
      • 1970-01-01
      • 2021-05-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-10-07
      • 2015-12-23
      相关资源
      最近更新 更多