【问题标题】:Parse file organised in a certain pattern以某种模式组织的解析文件
【发布时间】:2018-07-31 05:34:36
【问题描述】:

f是一个文件,如下图:

+++++192.168.1.1+++++
Port Number: 80
......
product: Apache httpd
IP Address: 192.168.1.1

+++++192.168.1.2+++++
Port Number: 80
......
product: Apache http
IP Address: 192.168.1.2

+++++192.168.1.3+++++
Port Number: 80
......
product: Apache httpd
IP Address: 192.168.1.3

+++++192.168.1.4+++++
Port Number: 3306
......
product: MySQL
IP Address: 192.168.1.4

+++++192.168.1.5+++++
Port Number: 22
......
product: Open SSH
IP Address: 192.168.1.5

+++++192.168.1.6+++++
Port Number: 80
......
product: Apache httpd
IP Address: 192.168.1.6

预期的输出是:

These hosts have Apache services:

192.168.1.1
192.168.1.2
192.168.1.3
192.168.1.6

我试过的代码:

for service in f:
    if "product: Apache httpd" in service:
        for host in f:
            if "IP Address: " in host:
                print(host[5:], service)

它只是给了我所有的 IP 地址,而不是安装了 Apache 的特定主机。

我怎样才能得到预期的输出?

【问题讨论】:

  • 什么是f?你打开的文件?
  • 当你的文件 sn-p 中没有这样的字符串时,你为什么要检查 "IP Address: " 字符串是否包含在行中?
  • @AzatIbrakov 抱歉打错了。我已经编辑了帖子。
  • 您正在以嵌套方式迭代相同的变量f。这没有意义。
  • 有时输入有“product: Apache http”,有时有“... httpd”。您只匹配“... httpd”。

标签: python formatted-input


【解决方案1】:

你也可以试试这个:

apaches = []
with open('ips.txt') as f:
    sections = f.read().split('\n\n')

    for section in sections:
        _, _, _, product, ip = section.split('\n')
        _, product_type = product.split(':')
        _, address = ip.split(':')

        if product_type.strip().startswith('Apache'):
            apaches.append(address.strip())

print('These hosts have Apache services:\n%s' % '\n'.join(apaches))

哪些输出:

These hosts have Apache services:
192.168.1.1
192.168.1.2
192.168.1.3
192.168.1.6

【讨论】:

    【解决方案2】:

    可能是这样的。 出于说明目的,我已内联数据,但它也可以来自文件。

    此外,我们首先收集所有主机数据,以防您还需要其他一些信息,然后打印出需要的信息。这意味着info_by_ip 看起来很像

    {'192.168.1.1': {'Port Number': '80', 'product': 'Apache httpd'},
     '192.168.1.2': {'Port Number': '80', 'product': 'Apache http'},
     '192.168.1.3': {'Port Number': '80', 'product': 'Apache httpd'},
     '192.168.1.4': {'Port Number': '3306', 'product': 'MySQL'},
     '192.168.1.5': {'Port Number': '22', 'product': 'Open SSH'},
     '192.168.1.6': {'Port Number': '80', 'product': 'Apache httpd'}}
    

    .

    代码:

    import collections
    
    data = """
    +++++192.168.1.1+++++
    Port Number: 80
    ......
    product: Apache httpd
    
    +++++192.168.1.2+++++
    Port Number: 80
    ......
    product: Apache http
    
    +++++192.168.1.3+++++
    Port Number: 80
    ......
    product: Apache httpd
    
    +++++192.168.1.4+++++
    Port Number: 3306
    ......
    product: MySQL
    
    +++++192.168.1.5+++++
    Port Number: 22
    ......
    product: Open SSH
    
    +++++192.168.1.6+++++
    Port Number: 80
    ......
    product: Apache httpd
    """
    
    ip = None  # Current IP address
    
    # A defaultdict lets us conveniently add per-IP data without having to
    # create the inner dicts explicitly:
    info_by_ip = collections.defaultdict(dict)
    
    for line in data.splitlines():  # replace with `for line in file:` for file purposes
        if line.startswith('+++++'):  # Seems like an IP address separator
            ip = line.strip('+')  # Remove + signs from both ends
            continue  # Skip to next line
        if ':' in line:  # If the line contains a colon,
            key, value = line.split(':', 1)  # ... split by it, 
            info_by_ip[ip][key.strip()] = value.strip()  # ... and add to this IP's dict.
    
    
    for ip, info in info_by_ip.items():
        if info.get('product') == 'Apache httpd':
            print(ip)
    

    【讨论】:

      【解决方案3】:

      你可以使用+++++作为你的分隔符,用下面的代码获取你想要的ip。

          with open('ip.txt', 'r') as fileReadObj:
          rows = fileReadObj.read()
          text_lines = rows.split('+++++')
          for i, row in enumerate(text_lines):
              if 'Apache' in str(row):
                  print(text_lines[i - 1])
      

      【讨论】:

        【解决方案4】:

        解释:

        with open(filename,'r') as fobj: # Open the file as read only
            search_string = fobj.read() # Read file into string
            print('These hosts have Apache services:\n\n')
            # Split string by search term
            for string_piece in search_string.split('Apache'):  
                # Split string to isolate IP and count up/back 2
                ip_addr = string_piece.split('+++++')[-2] 
                print(ip_addr)
        

        压缩:

        with open(filename,'r') as fobj:
            print('These hosts have Apache services:\n\n')
            for string_piece in fobj.read().split('Apache'):
                print('{}\n'.format(string_piece.split('+++++')[-2]))
        

        【讨论】:

          猜你喜欢
          • 2013-06-11
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2012-09-04
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多