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

awk perl regex sed

からの出力を調べる

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'

  97  user001  2012-01-21


ベストアンサー

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

GNU sedを使う

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

⚠ macOSでは、コメントでslmsteamer25が指摘しているように、デフォルトのsedコマンドは\eのような特殊文字をサポートしていません。代わりにbrew install gnu-sedを使ってインストールできるgsedを使ってください

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 は、グラフィックモード (色) のエスケープシーケンスに固有の文字 m だけではなく、[a-zA-Z] を使って他のすべてのエスケープシーケンスを削除することを提案しています。しかし、[a-zA-Z]は幅が広すぎて、削除しすぎてしまう可能性があります。Michał FaleńskiMiguel Mota は、それぞれ [mGKH][mGKF] を使って一部のエスケープシーケンスだけを削除することを提案しています。Britton Kerinは、gccエラー/警告の色を削除するためにKmに加えて使用する必要があることを示している(gcc 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

Using perl

オペレーティングシステムによっては、インストールされているsedのバージョンが制限されている場合があります (macOSなど)。perl コマンドは、より多くのオペレーティングシステムにインストール/更新しやすいという利点があります。Adam KatzPCRE\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'

Usage

Stuart Cardallさんのコメントで指摘されているように、このsedコマンドラインは、Ultimate Nginx Bad Bot(星1000個)というプロジェクトで、メールレポートを一掃するために使用されています 😉

136  olibre  2012-01-21


より良い脱出シーケンスリムーバーを発見しました。これをチェックしてください

perl -pe 's/\x1b\[[0-9;]*[mG]//g'

24  user204331  2013-03-05


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

ESC は 0x1B の 16 進数または 033 の 8 進数なので、正規表現には \x1B または \033 を使用しなければなりません

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

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

11  user1686  2012-01-21


シンプルなものがお好みなら、私のstrip-ansi-cliパッケージを使うことができます (Node.js 必須)

$ npm install --global strip-ansi-cli

ならば、こんな風に使いましょう

$ strip-ansi < colors.o

もしくは文字列で渡すだけ

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

9  Sindre Sorhus  2014-07-04


commandlinefuは、動作コマンドと同様にANSIカラーを削除したこの回答を提供しています

sed "s,\x1B\[[0-9;]*[a-zA-Z],,g"

ただの色のために、あなたが望む

 sed "s,\x1B\[[0-9;]*m,,g"

7  Tom Hale  2017-04-26


これは、すべての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配列(Esc[の “Control Sequence Introducer “で始まるエスケープコード配列で、カラーコードや他のテキスト装飾を構成するSelect Graphic Rendition配列よりも多くのものをカバーしています)の後に続きます

2 番目の置換では、末尾の文字を含む残りのシーケンスを削除し、ST (String Terminator, Esc\)で終わるようにしています。3番目の置換も同じですが、Operating System Command のシーケンスが BEL (\x07, \007, 多くの場合 \a) で終わるようになっています

4回目の交換で、残っていたエスケープを取り除きます

また、BELやその他の不明瞭なC0やC1制御文字のような他のゼロ幅ASCII文字を削除することも検討してみてください。私は、削除ソフトハイフンを含むs/[\x00-\x1f\x7f-\x9f\xad]+//gを使用しています。これはUnicodeの上位コードのゼロ幅文字を除外していますが、ASCII(Unicode \x00\xff)については網羅されていると思います。これを行う場合、これらは長いシーケンスに関与する可能性があるので、最後に削除してください

4  Adam Katz  2018-12-29


ansi2txt

Attention Required! | Cloudflare
cat typescript | ansi2txt | col -b
  • ansi2txt: ANSIカラーコードを削除します
  • col -b: ^Hまたは^Mを削除します

3  yurenchen  2019-12-28


回答済み」の質問がうまくいかなかったので、代わりにこの正規表現を作成して、perl Term::ANSIColorモジュールで生成されたエスケープシーケンスを削除しました

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

Grawityの正規表現は問題なく動作するはずですが、+の使用も問題なく動作するようです

2  castl3bravo  2013-03-13


“tput sgr0 “はこの制御文字を残しています^(b^[ ここでは、その点を考慮して修正しています

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

1  GustafAnkarloo  2019-06-27


パテを使ってインタラクティブなトップ出力を収集する際に追加された文字を削除するのと似たような問題がありましたが、これで解決しました

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

0  Michał Faleński  2013-07-03


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

perl -pe 's/\[[0-9;]*[mGKF]//g'

0  Miguel Mota  2017-09-16


アダム・カッツ@マイクの答えを組み合わせると

sed -E $'s|\x1b\\[[0-\\?]*[ -/]*[@-~]||g;
s|\x1b[PX^_][^\x1b]*\x1b\\\\||g;
s:\x1b\\][^\x07]*(\x07|\x1b\\\\)::g;
s|\x1b[@-_]||g'

これは、macos、linux、mingw64x (Git for Windows) で動作するはずです

注意: 古い GNU sed (4.2 以前) では、-E フラグを -r に置き換える必要があります (古い CentOS 6.0 のように)

正規表現の説明

1.ANSI CSIコードは、(順番に)構成されています

  1. One \x1b
  2. One [
  3. ゼロ以上のパラメータバイト 0x30-0x3f
  4. ゼロ以上の中間バイト 0x20-0x2f
  5. 最後の1バイト0x40-0x7f

2回目、3回目:実践では不慣れですが、リンク先のページで読んだことがあります

4番目余分なバイトがゼロであると仮定して、すべての残りのエスケープコードを取得するためのちょうどキャッチオール。これらのコードは、彼らが望むものは何でもできるので、データバイトが取り残される可能性がありますが、実際にはあまり使用されていないので、非常に可能性は低いです

0  Andy  2020-07-22


専用のツールもあります。ansifilter です。デフォルトの--text出力形式を使用します

ref: https://stackoverflow.com/a/6534712

0  Juan  2020-10-04


タイトルとURLをコピーしました