
次のファイルがあります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$
これらのエスケープ シーケンスが問題の原因となっている可能性があります。