テキストストリームからANSIカラーコードを削除する


73

からの出力を調べる

perl -e 'use Term::ANSIColor; print color "white"; print "ABC\n"; print color "reset";'

テキストエディタ(例:)ではvi、次のように表示されます。

^[[37mABC
^[[0m

出力ファイルからANSIカラーコードをどのように削除しますか?最善の方法は、出力を並べ替えのストリームエディターにパイプすることだと思います。

以下は機能しません

perl -e 'use Term::ANSIColor; print color "white"; print "ABC\n"; print color "reset";' | perl -pe 's/\^\[\[37m//g' | perl -pe 's/\^\[\[0m//g'

質問への答えではありませんが、出力をパイプするmoreless -R、テキストエディターの代わりにエスケープコードを色として解釈することもできます。
テルドン

回答:


98

文字^[[37m^[[0mANSIエスケープシーケンス(CSIコード)の一部です。これらの仕様も参照してください。

GNUを使用する sed

sed 's/\x1b\[[0-9;]*m//g'
  • \x1b(または\x1B)はエスケープ特殊文字です
    sed代替\eをサポートしません\033
  • \[ エスケープシーケンスの2番目の文字
  • [0-9;]* 色の値の正規表現です
  • m エスケープシーケンスの最後の文字

mac macOSでは、デフォルトsedコマンドは\eslmおよびsteamer25がコメントで指摘したような特殊文字をサポートしていません。代わりにgsedを使用してインストールできますbrew install gnu-sed

OPのコマンドラインの例:   (OPは元のポスターを意味します)

perl -e 'use Term::ANSIColor; print color "white"; print "ABC\n"; print color "reset";' | 
      sed 's/\x1b\[[0-9;]*m//g'

Tom Haleは、グラフィックモード(色)エスケープシーケンスに固有[a-zA-Z]の文字だけではなく、他のすべてのエスケープシーケンスを削除することを提案していmます。しかし、[a-zA-Z]幅が広すぎて、削除しすぎる可能性があります。MichałFaleńskiMiguel Motaは[mGKH][mGKF]それぞれand を使用して、いくつかのエスケープシーケンスのみを削除することを提案しています。Britton Kerinは、エラー/警告から色を削除するためKに加えて使用する必要があることも示しています(リダイレクトすることを忘れないでください)。mgccgcc 2>&1 | sed...

sed 's/\x1b\[[0-9;]*m//g'           # Remove color sequences only
sed 's/\x1b\[[0-9;]*[a-zA-Z]//g'    # Remove all escape sequences
sed 's/\x1b\[[0-9;]*[mGKH]//g'      # Remove color and move sequences
sed 's/\x1b\[[0-9;]*[mGKF]//g'      # Remove color and move sequences
Last escape
sequence
character   Purpose
---------   -------------------------------
m           Graphics Rendition Mode (including Color)
G           Horizontal cursor move
K           Horizontal deletion
H           New cursor position
F           Move cursor to previous n lines

を使用して perl

sed一部のオペレーティングシステムにインストールされているバージョンは制限されている場合があります(macOSなど)。このコマンドにperlは、一般に、より多くのオペレーティングシステムでインストール/更新が簡単になるという利点があります。Adam Katzは、PCREで\e(と同じ\x1b)を使用することを提案しています。

フィルタリングするコマンドの量に応じて正規表現を選択します。

perl -pe 's/\e\[[0-9;]*m//g'          # Remove colors only
perl -pe 's/\e\[[0-9;]*[mG]//g'
perl -pe 's/\e\[[0-9;]*[mGKH]//g'
perl -pe 's/\e\[[0-9;]*[a-zA-Z]//g'
perl -pe 's/\e\[[0-9;]*m(?:\e\[K)?//g' # Adam Katz's trick

OPのコマンドラインを使用した例:

perl -e 'use Term::ANSIColor; print color "white"; print "ABC\n"; print color "reset";' \
      | perl -pe 's/\e\[[0-9;]*m//g'

使用法

Stuart Cardallのコメントで指摘されているように、このsedコマンドラインはプロジェクトUltimate Ultimate Nginx Bad Bot(1000スター)で使用され、電子メールレポートをクリーンアップします;-)


2
sedコマンドと説明をありがとう。:)
レッドサンドロ

2
一部のカラーコード(Linuxターミナルなど)には接頭辞が含まれています。たとえば、正規表現に1;31m追加;したほうがいいcat colored.log | sed -r 's/\x1b\[[0-9;]*m//g'場合があります。そうでない場合は削除されません。
レッサンドロ14

1
これは、github.com / mitchellkrogza / nginx-ultimate-bad-bot-blocker / blob / ...で使用して、電子メールレポートをクリーンアップするのに最適です。
スチュアートカーダル

2
OSXバージョンはsed示された例では機能しませんでしたが、gsedバージョンは機能します。
slm

2
OSX sedに関するslmのコメントの詳細なコンテキスト:\ x1bなどの制御文字をサポートしていません。例えば、stackoverflow.com/a/14881851/93345。を介してgsedコマンドを取得できますbrew install gnu-sed
スチーマー25


10

何と表示され^[ているではない ^[。またはESCによって生成されるASCII 文字です(表記はCtrlキーを意味します)。EscCtrl[^

ESC0x1B 16進数または033 8進数であるため、正規表現を使用する\x1B必要\033があります。

perl -pe 's/\033\[37m//g; s/\033[0m//g'

perl -pe 's/\033\[\d*(;\d*)*m//g'

6

シンプルなものが必要な場合は、strip-ansiモジュールを使用できます(Node.jsが必要です)。

$ npm install --global strip-ansi-cli

次に、次のように使用します。

$ strip-ansi < colors.o

または、文字列を渡すだけです:

$ strip-ansi '^[[37mABC^[[0m'

これはcatUUOC)の役に立たない使用です— strip-ansi colors.o少なくとも可能strip-ansi < colors.oです。
スコット

1
@Scott確かに、あなたもできますstrip-ansi < colors.oが、経験から人々はパイピングに精通しています。答えを更新しました。
シンドレソルハ16

良いシンプルなソリューション
Penghe Geng


2

「答えられた」質問は私にとってはうまくいかなかったので、代わりにperl Term :: ANSIColorモジュールによって生成されたエスケープシーケンスを削除するためにこの正規表現を作成しました。

cat colors.o | perl -pe 's/\x1b\[[^m]+m//g;

Grawityの正規表現は正常に機能するはずですが、+を使用しても正常に機能するようです。


4
(1)どういう意味The "answered" questionですか?受け入れられた答えを意味しますか?(2)このコマンドは、引用符が不一致(不均衡)であるため、機能しません—実行すらしません。(3)これはcatUUOC)の無用な使用です—できるはずです。(4)ファイルに含まれるコードについて何か言ったことはありますか?perl -pe command colors.o.o
スコット

2

これはすべてのANSIエスケープシーケンスの正式な削除だと思います。

perl -pe '
  s/\e\[[\x30-\x3f]*[\x20-\x2f]*[\x40-\x7e]//g;
  s/\e[PX^_].*?\e\\//g;
  s/\e\][^\a]*(?:\a|\e\\)//g;
  s/\e[\[\]A-Z\\^_@]//g;'

(perlは、他の多くの言語(sedではない)と\e同様に、端末に表示されるエスケープ文字としてEsc\x1bまたは\033コードによって受け入れられることに注意してください^[

このperlコマンドは、必要に応じて1行ですべて実行できますが、4つの置換があります。

最初は、CSIシーケンス(カラーコードやその他のテキスト装飾を構成するSelect Graphic RenditionシーケンスEsc[よりも多くをカバーするの「Control Sequence Introducer」で始まるエスケープコードシーケンス)の後です。

2番目の置換は、後続文字を含む残りのシーケンスを削除し、ST(文字列ターミネーターEsc\)で終了します。第三の交換は同じものですが、また可能にするオペレーティングシステムのコマンド・シーケンスは、で終わるBEL\x07\007、多くの場合\a)。

4番目の置換は、残りのエスケープを削除します。

また、BELなどのその他のゼロ幅ASCII文字や、より不明瞭なC0およびC1制御文字を削除することも検討してください。私は使用していますがs/[\x00-\x1f\x7f-\x9f\xad]+//g、これにはDeleteSoft Hyphenも含まれています。これは、ユニコードのより高いコード化されたゼロ幅文字を除外しますが、ASCII(ユニコード\x00- \xff)を網羅していると思います。これを行う場合、より長いシーケンスに関与する可能性があるため、これらを最後に削除します。


1

「tput sgr0」はこの制御文字を残しました^(B ^ [これ
は、それを処理するための修正版です。

perl -pe 's/\e[\[\(][0-9;]*[mGKFB]//g' logfile.log

これに感謝します...これはtput sgr0、他の解決策が決して取り除くことができないようであるということを取り除くために私のために働きました。
TxAG98

0

パテを介したインタラクティブなトップ出力の収集から追加された文字を削除することで同様の問題が発生し、これが役立ちました:

cat putty1.log | perl -pe 's/\x1b.*?[mGKH]//g'

3
これはcatUUOC)の無駄な使用です。perl -pe command putty1.log
スコット

0

これは私のために働いたものです(Mac OS Xでテスト済み)

perl -pe 's/\[[0-9;]*[mGKF]//g'
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.