コマンドの出力を色でフィルターする


13

出力をフィルタリングする方法を提供しないユーティリティを実行しています。出力のテキストには、特定の機能が失敗したことを示すものはありませんが、赤で表示されます。出力は非常に長いため、最後にエラーの数を報告するとき、エラーが発生した出力を表示するために常にスクロールすることはできません。

赤以外のテキストを除外するにはどうすればよいですか?

擬似コード:

dolongtask | grep -color red

編集

コマンド出力を他の色だけでなく、私はフィルタリングできるようにする必要が出て、すべてのテキストではありません赤を。また、テキストの色は複数行です。


1
明らかな質問をして申し訳あり>&1ませんが、すべての出力はオンになっていますか?もしそうなら、赤いものは消えないよ2>/dev/nullね?
mikeserv 14

回答:


15

色の切り替えは、テキストに埋め込まれたエスケープシーケンスを介して行われます。常に、プログラムはANSIエスケープシーケンスを発行します。これは、現在ほとんどすべての端末がサポートしているためです。

前景色を赤に切り替えるエスケープシーケンスは\e[31m\e、エスケープ文字(8進033、16進1b、ESCとも呼ばれる^[)、およびその他のさまざまな指定を指定します。30〜39の範囲の数字で前景色を設定します。他の数字は異なる属性を設定します。\e[0mすべての属性をデフォルト値にリセットします。cat -vプログラムが何を印刷するかを確認するために実行します。\e[0;31m最初にすべての属性をリセットしたり\e[3;31、イタリックをオンにしたり(多くの端末はサポートしていません)などのバリアントを使用します。

ksh、bash、またはzshでは$'…'、引用符内でバックスラッシュエスケープを有効にするために使用できます。これにより、入力$'\e'してエスケープ文字を取得できます。その後、渡すバックスラッシュを2倍にする必要があることに注意してくださいgrep。では/bin/sh"$(printf \\e)"リテラルエスケープ文字を使用または入力できます。

GNU grep -oオプションを使用すると、次のスニペットは赤いテキストをフィルタリングします。エスケープシーケンス\e[31mで始まり、どちらか\e[0mまたは\e[30m同じ行で終わり、埋め込みエスケープシーケンスが含まれていないことを前提としています。

grep -Eo $'\e\\[31m[^\e]*\e\\[[03]?m'

次のawkスニペットは、複数行であっても赤いテキストを抽出します。

awk -v RS='\033' '
    match($0, /^\[[0-9;]*m/) {
        color = ";" substr($0, 2, RLENGTH-2) ";";
        $0 = substr($0, RLENGTH+1);
        gsub(/(^|;)0*[^03;][0-9]*($|;)/, ";", color);
        red = (color ~ /1;*$/)
    }
    red'

色を変更するコマンドを保持するバリエーションがあります。これは、複数の色(ここでは赤とマゼンタ)をフィルタリングする場合に便利です。

awk -v RS='\033' '
    match($0, /^\[[0-9;]*m/) {
        color = ";" substr($0, 2, RLENGTH-2) ";";
        printf "\033%s", substr($0, 1, RLENGTH);
        $0 = substr($0, RLENGTH+1);
        gsub(/(^|;)0*[^03;][0-9]*($|;)/, ";", color);
        desired = (color ~ /[15];*$/)
    }
    desired'

awkソリューションは私のために働いた。出力で色を保持する方法はありますか?
km6zla 14

@ ogc-nickすべて赤の出力が必要ですか?printf '\e[31m'; awk …; printf '\e[0m'
ジル「SO-悪であるのをやめる」14

出力で保持するためにフィルタリングする色に関係なく。
km6zla 14

@ ogc-nick編集をご覧ください。
ジル「SO-悪であるのをやめる」14

6

grepに制御文字を検索させることができます。制御文字の一部は、端末できれいな色を作成する役割を果たします。

dolongtask | grep '[[:cntrl:]]'

たとえば、これは赤い「テスト」をgrepにエコーし、制御文字に囲まれているためにそれを見つけます。

$ echo -e '\033[00;31mtest\033[00m' | grep --color=none '[[:cntrl:]]'
test     <-- in red

これ--color=noneは、grepが一致した出力に独自の色付けを適用せず、制御文字がシェルによって解釈されるように行全体を忠実に印刷することを確認するためです。


いいね さらに進んで、具体的に赤のようなことをしgrep -E $'\033\[0?[01];31m.+?\033\[0?0m'たりgrep -Po '\033\[0?[01]+;31m\K.+?(?=\033\[0?0m)'、具体的に赤をテストしたりできるのだろうか
スチールドライバー14

私はあなたが提案するような正規表現を考え始めましたが、それらを機能させる前に私はつまずきました[[:cntrl:]]。私はあなたのものをテストしました、そして、彼らは私のために働きます、すなわち。赤と一致し、他の色と一致しない。
サヴァント14

素晴らしい作品ですが、どんな色にもマッチします。私は質問でそれを言及しませんでしたが、他の多くの色も出力され、私は赤いものを見たいだけです。シンプルで動作するコードの場合は+1。
km6zla 14
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.