【问题标题】:Searching in a text and save in string, python在文本中搜索并保存在字符串中,python
【发布时间】:2013-12-06 20:59:52
【问题描述】:

作为 Linux 中 ifconfig 命令的结果,我只想将 int addr 和 Mask 保留在两个字符串中:

eth0      Link encap:Ethernet  HWaddr 22:33:0a:e9:15:76
          inet addr:10.244.21.118  Bcast:10.244.21.127  Mask:255.244.255.192
          inet6 addr: fe80::0050:aff:fee9:1576/64 Scope:Link
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:807304 errors:0 dropped:0 overruns:0 frame:0
          TX packets:611741 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000
          RX bytes:253087331 (241.3 MiB)  TX bytes:167902811 (160.1 MiB)

最终得到这个:

inet_addr: "10.244.21.118"
mask="255.244.255.192"

有没有更快的方法?我唯一的想法是解析每一行,然后搜索 int addr 并删除名称......但我不知道它是否有效。

【问题讨论】:

    标签: python search


    【解决方案1】:

    python中的3个通用选项:

    • 从对ifconfig 的shell 调用中解析它。您当前的方法以及所有其他答案的方法。
    • 使用套接字。设置一个 UDP 套接字连接到外部主机,查看它的 sockname 并找到它的掩码。您将不得不处理一些(非常)低级的 API。
    • 使用外部模块。例如python-ifconfig

    这是使用套接字的第二种方法的基本形式:

    import socket
    import fcntl
    import struct
    
    s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) #UDP
    
    s.connect(('google.com',0)) #prepare UDP socket to connect to some external host
    
    s.getsockname()
    Out[17]: ('10.0.2.15', 56965)
    
    socket.inet_ntoa(fcntl.ioctl(s, 0x891b, struct.pack('256s', 'eth0'))[20:24])
    Out[18]: '255.255.255.0'
    

    感谢this thread 中的回答者提供了掩码解决方案,我不知道那些操作码是我头顶上的:)

    【讨论】:

      【解决方案2】:

      可能是这样的?

      #!/usr/local/cpython-3.3/bin/python
      
      import re
      
      def give_string():
          string = '''
      eth0      Link encap:Ethernet  HWaddr 22:33:0a:e9:15:76
                inet addr:10.244.21.118  Bcast:10.244.21.127  Mask:255.244.255.192
                inet6 addr: fe80::0050:aff:fee9:1576/64 Scope:Link
                UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
                RX packets:807304 errors:0 dropped:0 overruns:0 frame:0
                TX packets:611741 errors:0 dropped:0 overruns:0 carrier:0
                collisions:0 txqueuelen:1000
                RX bytes:253087331 (241.3 MiB)  TX bytes:167902811 (160.1 MiB)
          '''
          return string
      
      def main():
          string = give_string()
          regex = re.compile('^.*inet addr:\s*(\d+\.\d+\.\d+\.\d+) .*Mask:\s*(\d+\.\d+\.\d+\.\d+).*$', re.MULTILINE | re.DOTALL)
          match = regex.match(string)
          ip_address = match.group(1)
          subnet_mask=match.group(2)
          print(ip_address, subnet_mask)
      
      main()
      

      顺便说一句,我通常说人们过度使用正则表达式,但这是一个很好的例子。

      【讨论】:

        【解决方案3】:

        使用Regular Expressions,您可以完成此操作。下面的代码将所有内容放在 devices 列表中,但 for 循环。

        import re
        
        ifconfig = """eth0      Link encap:Ethernet  HWaddr 22:33:0a:e9:15:76
                  inet addr:10.244.21.118  Bcast:10.244.21.127  Mask:255.244.255.192
                  inet6 addr: fe80::0050:aff:fee9:1576/64 Scope:Link
                  UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
                  RX packets:807304 errors:0 dropped:0 overruns:0 frame:0
                  TX packets:611741 errors:0 dropped:0 overruns:0 carrier:0
                  collisions:0 txqueuelen:1000
                  RX bytes:253087331 (241.3 MiB)  TX bytes:167902811 (160.1 MiB)
        """
        
        devices = []      
        for d in re.findall(r'^(\S+).*?inet addr:(\S+).*?Mask:(\S+)', ifconfig, re.S | re.M):
            devices.append((d[0], d[1], d[2]))
        
        print devices
        

        输出:

        [('eth0', '10.244.21.118', '255.244.255.192')]
        

        最后,稍作修改,您就可以在运行ifconfig 时让这个循环遍历出现的每个设备。在re.findall 循环之前,您还需要一个for 循环,以便按设备拆分它。我相信像for dev in ifconfig.split('\n\n'): 这样的东西会按设备正确拆分。

        【讨论】:

          【解决方案4】:

          由于 ifconfig 的输出是可预测的,因此不需要正则表达式。此代码仅使用常用的 python 字符串工具捕获输出并解析:

          from subprocess import check_output
          lines = check_output(["/sbin/ifconfig", "eth0"]).split('\n')
          line = lines[1] # Get the 2nd line
          parts = line.split()
          inet_addr = parts[2]
          mask = parts[-1].split(':')[1]
          print 'inet_addr=%s mask=%s' % (inet_addr, mask)
          

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2011-09-13
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多