简体   繁体   English

解析子流程Check_Output的表格输出

[英]Parse tabular output from Subprocess Check_Output

I'm working on a Python(3.6) project in which I need to parse data from a tabular output of subprocess.check_output. 我正在研究一个Python(3.6)项目,其中需要从subprocess.check_output的表格输出中解析数据。

Here's How I'm using this: The output is: 这是我的使用方式:输出为:

NAME      HOSTS     ADDRESS           PORTS     AGE
mysvcs    *         107.178.250.150   80        1m

This out loads an empty column for ADDRESS like this: 这样会为ADDRESS加载一个空列,如下所示:

NAME      HOSTS     ADDRESS           PORTS     AGE
mysvcs    *                           80        1m

But after few moments it loads the 107.178.250.150 in the 3rd column of second row. 但是片刻之后,它会在第二行的第三列中加载107.178.250.150 So, how can I get this address when it has been populated. 因此,填充后如何获取该address Here's how I'm trying: 这是我的尝试方式:

address = subprocess.check_output(["kubectl get ing | awk '{print $3}'"], shell=True)
            all_address = out_ip.decode().split('\n')
            print(all_address)
            address = all_address[1]
            print(address)
            if not address:
                while address == '':
                    out_address = subprocess.check_output(["kubectl get ing | awk '{print $3}'"], shell=True)
                    all_address = out_ip.decode().split('\n')
                    ip = all_address[1]
                    print(address)

But it's even not running the while loop and output as: 但它甚至没有运行while循环并输出为:

b'ADDRESS\\n80\\n' ['ADDRESS', '80', ''] 80


Update: Here's how I have tried stovfl's answer: 更新:这是我尝试stovfl答案的方式:

            ip = ''
            # Limit to 5 loops
            for n in range(5):
                result = subprocess.check_output(["kubectl get ing | awk '{print $3}'"], shell=True)
                # Make a List from the result, spliting at NewLine
                _list = result.decode().split('\n')

                # Check if Value 2 (Index==1) matches a IP Address
                if re.match(r'(\d+\.\d+\.\d+\.\d+)', _list[1]):
                    ip = _list[1]
                    print("match:{}".format(_list[1]))
                    # End the loop
                    break

                # Wait a second, before next try
                time.sleep(1)

                address = 'http://' + ip

Question : Parse tabular output, loop until results a IP Address 问题 :解析表格输出,循环直到得到一个IP地址

import time, re

# Limit to 5 loops
for n in range(5):
    result = subprocess.check_output(["kubectl get ing | awk '{print $3}'"], shell=True)
     # Make a List from the result, spliting at NewLine
    _list = result.decode().split('\n')
    # DEBUG
    print("list:{}".format(_list))

    # Check if Value 2 (Index==1) matches a IP Address
    if re.match(r'(\d+\.\d+\.\d+\.\d+)', _list[1]):
        print("match:{}".format(_list[1]))
        # End the loop
        break

    # Wait a second, before next try
    time.sleep(1)

Tested with Python: 3.4.2 使用Python测试:3.4.2

If you are using Python 3.5 or newer, you can upgrade to subprocess.run() which has some useful features. 如果您使用的是Python 3.5或更高版本,则可以升级到具有一些有用功能的subprocess.run()

I would also factor out the shell and the Awk pipeline. 我还将考虑外壳程序和Awk管道。

addr = None
while True:
    result = subprocess.run(
        ['kubectl', 'get', 'ing'],
        stdout=subprocess,PIPE, stderr=subprocess.PIPE,
        text=True, check=True)
    lines = result.stdout.split('\n')
    # [1:] - skip header line
    # [:-1] - skip empty element after last newline
    for line in lines[1:-1]:
        # replace Awk
        filelds = line.split()
        if len(fields) > 2 and '.' in fields[2]:
            addr = fields[2]
            break
    if addr:
        break
    time.sleep(1)

The text=True takes care of automatically normalizing the output to Unicode with standard line breaks. text=True负责使用标准换行符将输出自动归一化为Unicode。 (Before Python 3.7 this was universal_newlines=True .) (在Python 3.7之前,这是universal_newlines=True 。)

Here's a working solution for Python(3.6): 这是适用于Python(3.6)的可行解决方案:

addr = None
while addr is None:
     out = subprocess.check_output(["kubectl get ing | awk '{print $3}'"], shell=True)
     print(out)
     all_addr = out.decode().split('\n')
     if re.match(r"\d+\.\d+\.\d+\.\d+", str(all_addr[1])):
         addr = all_addr[1]
         print('Address is: {}'.format(addr))
     else:
         addr = None

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM