69227


Cのアプリ実行時に標準出力されるログを入力としてリアルタイムに指定文字の検出とデータ抽出を行い、`top`
コマンドのように随時更新し表示し続けたいです。参考になるコードを教えてください。

Pythonのsubprocessで一ラインずつ拾って指定文字を含むラインからデータ抽出する方法を考えています。

入力となる標準出力と 希望している出力のイメージは以下の通りです。

### 標準出力の例

[code]

    ABE1  time  retire  limit  offset  1000
    ABE1  time  retire  limit  delay  1000
    hogehoge
    ABE2  time  retire  limit  offset  2000
    ABE2  time  retire  limit  delay  2000
    topoconfuckyouhogehoge
    ABE2  time  retire  limit  offset  2000
    ABE2  time  retire  limit  delay  2000
    ABE1  time  retire  limit  offset  1500
    ABE1  time  retire  limit  delay  1500
    .
    .
    
    
[/code]

### 出力例

[code]

    ABE1: offset average 1250 max-min 500 variance 0.8
    ABE1: delay  average 1250 max-min 500 variance 0.8
    ABE2: offset average 1250 max-min 500 variance 0.8
    ABE2: delay  average 1250 max-min 500 variance 0.8
    ---------------------------------------------------
    ABE1          ABE2
    offset  delay  offset  delay
    1000    200    2000    210
    1100    100    1000    340
    1400    300    1300    200
    800     200    2100    100
    .
    .
    
[/code]


CC BY-SA 4.0
2020-08-03T12:35:49.507
69214
2020-08-04T03:49:13.567
2020-08-03T16:00:11.337
3060
41344
question
python
Pythonで標準出力から指定文字の検出とデータ抽出をし、topコマンドのように並べて表示したいのですが参考になるコードを教えてください


ご質問の文章にありますように、subprocessで一ラインずつ拾って指定文字を含むラインからデータ抽出するコードを組むべきと思います。

下記は標準出力をリアルタイムに読み取ってオフセットの平均を出力する例です。  
WindowsでPopenを用いてpowershellスクリプトを呼び出し、コンソールの表示をclsコマンドでクリアしながら再描画しています。

**サンプルコード:**

[code]

    import os
    import sys
    import subprocess
    from statistics import mean
    
    p = subprocess.Popen(["powershell", r".\test.ps1"], shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
    
    # ToDo うまく対応する
    offsets = {"ABE1": [], "ABE2": []}
    
    for line in iter(p.stdout.readline, b''):
        ss = line.decode().rstrip().split()
        if len(ss) < 6:
            continue
        # ToDo うまく対応する
        if ss[4] == "offset" and ss[0] in offsets:
            # Windowsでコンソール画面クリア
            os.system("cls")
            offsets[ss[0]].append(int(ss[5]))
            for key in offsets:
                list = offsets[key]
                if len(list) == 0:
                    continue
                print("{}: offset average {}".format(key, mean(list)))
    
[/code]

**Powershellスクリプト** (test.ps1)

[code]

    $lines = @("ABE1  time  retire  limit  offset  1000",
    "ABE1  time  retire  limit  delay  1000",
    "hogehoge",
    "ABE2  time  retire  limit  offset  2000",
    "ABE2  time  retire  limit  delay  2000",
    "totemoutsukushikihogehoge",
    "ABE2  time  retire  limit  offset  1000",
    "ABE2  time  retire  limit  delay  2000",
    "ABE1  time  retire  limit  offset  1500",
    "ABE1  time  retire  limit  delay  1500")
    
    foreach($l in $lines) {
        $l
        sleep(1)
    }
    
[/code]


CC BY-SA 4.0
2020-08-04T03:49:13.567
69227
2020-08-04T03:49:13.567
9820
69214
answer