web-dev-qa-db-ja.com

sedを使用して継続的にストリーミング出力を操作する方法は?

私は非技術者向けのプレゼンテーションをまとめています。値の連続ストリームを出力するプログラムをbashで実行していますが、そのうちのいくつかは重要です。重要な結果が表示されるときに強調表示して、聴衆が自分の頻度を理解できるようにします。問題は、実行中のストリームでsedを操作できないことです。次のように結果をファイルに入れれば、うまくいきます。

cat output.txt | sed "s/some text/some text bolded/"

しかし、次のように実行中の出力で同じことを試みると:

command | sed "s/some text/some text bolded/"

sedは何もしません。何かご意見は?

ランバートは指摘するのに十分役立つため、sedは何もしないという私の発言はあいまいでした。何が起こっているのかというと、プログラムはstdoutを介してパイプされていても、通常どおりstderrsedに書き込まれていないと確信しています)に出力します。

問題は、コマンドが2番目のプログラムを呼び出し、それが標準出力に出力されることです。最初のプログラムによって印刷される数行があります。これらは編集できます。次に、2番目のプログラムによって出力される値のストリームがあります。これらは編集できません。

Perlおよびawkメソッドも機能しません。

13
P Jones

コマンドの出力がバッファリングされる可能性があります。コマンドが端末に書き込むと、バッファはすべての改行でフラッシュされるため、期待した速度で表示されることがわかります。コマンドがパイプに書き込む場合、バッファーは数キロバイトに達したときにのみフラッシュされるため、大幅に遅延します。したがって、これは標準入出力ライブラリのデフォルトの動作です。

コマンドが出力をバフェットしないようにするには、unbuffer(expectから)またはstdbuf(from GNU coreutils)を使用)を使用できます。

unbuffer command | sed …
stdbuf -o0 command | sed …

sedにはそのためのオプションがあります:

-u、-unbuffered

これにより、入力ファイルから最小量のデータが読み込まれ、出力バッファーがより頻繁にフラッシュされます。見る man sed 詳細については。

4
ChennyStar

私はawkを使います

  command | awk '/some important stuff/ { printf "%c[31m%s%c[0m\n",27,$0,27 ; next }
  { print ; } '

どこ

  • /some important stuff/ sedのように重要な行を選択
  • printf "%c[31m%s%c[0m\n",27,$0,27 ;赤で印刷
    • 緑、黄色には32、33を使用...
    • $ 1、$ 2、特定のフィールドを選択するために使用できます
  • 他の行は「そのまま」印刷されます

重要な点は、commandが行をフラッシュする必要があることですが、出力が多い場合はそうなります。

2
Archemar

Perlの方法:

command | Perl -pe 's/(stuff)/\x1b[1m$1\x1b[0m/g'

または継続的な出力:

出力contのbashスクリプト:

#!/bin/bash
while [ true ]
do
   echo "Some stuff"
done

でテストする:

./cont | Perl -pe 's/(stuff)/\x1b[1m${1}\x1b[0m/g'
  • \x1b[1m-太字または強度の増加
  • ${1}-バックリファレンス
  • \x1b[0m-すべての属性をリセットします

出力:

いくつかもの
一部もの
一部もの
一部もの

その他のエスケープコード ここ

1
A.B.