web-dev-qa-db-ja.com

grepを使用すると画面に奇妙な記号が表示されますか?

./trans ... command output showing escape codes

何がこれを引き起こしているのでしょうか? grepを使用しない場合、ISOコードと空のスペースのみが表示されます。

使用ソフトウェア

コマンド:./trans --id --input /path/to/txt | grep ISO | grep [a-z]

root@box /test # alias grep
alias grep='grep --color=auto'
root@box /test # type grep
grep is aliased to `grep --color=auto'

通常の出力:

trans command output with readable text and URLs

12
Freedo

スクリーンショットは、テキストのレンダリングを制御する、細分化された ANSIカラーコード を示しているようです。太字/明るいテキストは、_␛[1m_というシーケンスで生成されます。これは通常、端末によって解釈され、画面に直接表示されません。テキストの次のビットを明るくするだけです。 un grepped出力のスクリーンショットは、各行のラベルと値の色の違いを示しているため、元の出力はそれらを使用しています。

そのシーケンスは、最後のgrepによって壊れているようです。これは、コードの「m」に一致し(文字_[a-z]_であるため)、赤で強調表示しようとしました。その結果、端末が処理できなかった部分的なエスケープシーケンスが残りました。

エスケープ文字__はU + 001Bです。これは、不明な文字のボックスに表示される16進数です。表示されるのは、エスケープ(ボックス)、_[_、_1_、赤いmの後に予期される一致するテキスト「eng」が続きます。最後に同じことが起こります。 「22」(「通常の色と強度」の数値コード)。


壊れた出力は本当に:

 ␛[1␛[31mmeng␛[22m␛[22␛[31mm␛[22m 

ここで、_␛[31m_はテキストを赤にし、_␛[22m_はテキストを白に戻します。どちらもgrepによってm文字を囲んで元のテキストに挿入されます。オリジナルはちょうど:

␛[1meng␛[22m 

これは明るい "eng"で、通常のテキストに戻ります。

これを確認するには、最後のgrepを_grep --color=always_に変更し、hexdumpにパイピングします。これにより、印刷できないすべての文字と、端末で解釈される文字が表示されます。


これにはいくつかの方法で対処できます。 1つは、今のところエイリアスなしでgrepを使用することです。

_./trans --id --input /path/to/txt | grep ISO | \grep [a-z]
_

バックスラッシュは一時的にエイリアスをスキップし、grepを直接実行します。

もう1つは、元のコマンドからANSIコードを取り除くことです。これにはいくつかの提案があります この質問では

_./trans --id --input /path/to/txt | Perl -pe 's/\e\[[\d;]*m//g' | grep ISO | grep [a-z]
_

さらに別のオプションは、最後に無関係なパイプを追加することです:

_./trans --id --input /path/to/txt | grep ISO | grep [a-z] | cat
_

最終的なgrepの出力はTTYに直接送信されるのではなく、パイプを介してcatに送信されるため、色付きの強調表示は挿入されません。

おそらく、最良のオプションは、変換シェルが端末ではない場合、最初の場所でそれ自体の出力で端末制御シーケンスの使用を停止することです。それには、あなたからその作者へのバグレポートと、Translate Shellのansi()関数へのコード修正が適切に含まれますが、多少は回避できます。

_TERM=dumb ./trans --id --input /path/to/txt | grep ISO | grep [a-z]
_

これは、変換シェルの環境でdumb端末タイプを渡します。これは、少なくともECMA-48カラーサポートがないと認識します。 (悲しいことに、Translate Shellはterminfoを使用せず、独自のコードに、それが理解する端末タイプとそれが使用する制御シーケンスをハードワイヤーしているだけです。)

28
Michael Homer