正規表現ベースのコマンドの出力を縮小するツールはありますか?

正規表現ベースのコマンドの出力を縮小するツールはありますか?

いくつかのアプリケーションステータスを出力するコマンドがあるとします。このコマンドは永久に(またはCCまで)実行され、アプリケーション内で何かが発生した場合は1行を出力します。次の形式で出力されます。

State N: Stuff M happened

collapse_prog私は私が提供する正規表現に基づいてコマンド出力行を取得し、以前の状態を上書きするプログラムが欲しいです。たとえば、入力正規表現がState(\ d +)であるとし、次のコマンドを実行します。

my_command | collapse_prog

そしてmy_command出力

State 1: Stuff A happened
State 2: Stuff B happened

その後、collapse_progそのまま表示する必要がありますが、my_command別の行を出力した後

State 1: Stuff C happened

これにより、collapse_prog次のような出力が出なければなりません。

State 1: Stuff C happened
State 2: Stuff B happened

すでにそのようなプログラムがありますか?

ベストアンサー1

非常に基本的なソリューションTxR不明な言葉:

$ program | txr stcoll.tl

どこstcoll.tl

(let ((states (hash)))
  (whilet ((line (get-line)))
    (when-match `State @s: @status` line
      (set [states s] status)
      (dohash (s status states)
        (put-line `State @s: @status`))
      (put-string `\e[@(len states)A`)
      (flush-stream *stdout*))))

どのように機能するかは、各週の最新の状態がメインIDに基づいてハッシュテーブルに格納されることです。ステータス行を取得するたびにハッシュを更新してから印刷します。印刷後、ESC[<n>AVT100 / ANSIエスケープシーケンスを使用してカーソルをその行だけ後ろに移動します。これは、端末ウィンドウが全ての状態に対して十分に高いと仮定する。これは非常にシンプルなインタラクティブビューツールに適しています。

より複雑なプログラムは、タイムアウト(例:1秒)後に標準入力をポーリングします。または設定可能です。次に、入力ループを通過するたびに行が受信されているかタイムアウトしているかにかかわらず、ハッシュが変更されたことを確認し、変更された場合は、最後の更新以降に更新サイクルが期限切れになったかどうかを確認します。この場合は、ディスプレイを更新してください。

これらのプログラムは、入力がすぐに到着するとディスプレイをより効率的に更新します。

ここにいる:

(let* ((states (hash))
       (last-time 0)
       (hash-touched nil)
       (unbuf-stdin (open-fileno (fileno *stdin*) "u"))
       (poll-list (vec (cons unbuf-stdin poll-in))))
  (while t
    (if (poll poll-list 1000)
      (let ((line (get-line unbuf-stdin)))
        (when-match `State @s: @status` line
          (set [states s] status
               hash-touched t))))
    (let ((now (time)))
      (when (and hash-touched (>= (- now last-time) 1))
        (dohash (s status states)
          (put-line `State @s: @status`))
        (put-string `\e[@(len states)A`)
        (flush-stream *stdout*)
        (set hash-touched nil
             last-time now)))))

プログラムが吹き出ていても、1秒間隔でアップデートになります。このプログラムを使用してテスト入力を生成しています。 20の状態のいずれかをランダムに増やし、ランダムな一時停止で更新を印刷します。

(let* ((nstates 20)
       (states (vector nstates 0)))
  (while t
    (let ((choice (rand nstates)))
      (inc [states choice])
      (put-line `State @choice: @[states choice]`)
      (flush-stream *stdout*)
      (if (zerop (rand 4) )
        (usleep (rand 500000))))))

おすすめ記事