色で grep しても何も返されないのはなぜですか?

色で grep しても何も返されないのはなぜですか?

次のファイルがありますfoo.txt:

This is the first line.
This is the middle line.
This is the last line.

そして、私は真ん中の行を単語だけで grep してmiddle、その周囲を返すようにしています (例として)。こうすることで、文全体を強調表示することができます (これは、コンテキスト オプションを使用する場合に特に便利です)。

それする色なしで作業する:

$ grep -o --color=none '.\+ middle .\+' foo.txt
This is the middle line.

しかし同じコマンドしない色を扱う:

$ grep -o --color=auto '.\+ middle .\+' foo.txt
(empty line)

注:-oこれがなくても違いはありません。

ただし、行の前半のみをフィルタリングする場合は機能します。

$ grep -o --color=auto '.\+ middle' foo.txt
This is the middle

しかし、後半部分('middle .\+')はそうではありません。

なぜこれが期待どおりに動作しないのでしょうか。また、どうすれば修正できるのでしょうか。これはバグでしょうか。それとも、何らかの理由で 2 つの正規表現を同時に使用できないのでしょうか。


OS Xでテスト済み:

$ grep --version
grep (BSD grep) 2.5.1-FreeBSD

Linuxでも動くようなので、混乱しています。

答え1

grep をカラーオプション付きで使用すると、端末にカラーのオン/オフを指示する追加のエスケープ文字シーケンスが生成されます。これらのシーケンスは、適切に解釈されず、予期しない結果を引き起こすリスクがあります。
これらは、grep の出力をキャプチャすることで確認できます。

色なし

grepsの出力を送信するoutput.txt

% grep -o --color=none '.\+ middle .\+' foo.txt > output.txt
% cat -etv output.txt 
This is the middle line.$

色付き

オプションを使用して色を強制します--color=always。grep 出力をリダイレクトすると、可能であれば、強調表示した理由により色がオフになり、エスケープ文字によって副作用が発生する可能性があります。

% grep -o --color=always '.\+ middle .\+' foo.txt > output.txt
% cat -etv output.txt                                             
^[[01;31m^[[KThis is the middle line.^[[m^[[K$

これらのエスケープ シーケンスが問題の原因となっている可能性があります。

関連情報