web-dev-qa-db-ja.com

grepのコンテキスト「group-separator」として空の行を使用する

グループ区切り文字として、コンテキスト、カラー、空白行を含むgrep出力が必要です。この 質問 では、カスタムgroup-separatorを定義する方法を学び、次のようにgrepコマンドを作成しました。

grep --group-separator="" --color=always -A5

ただし、グループセパレータは実際には空ではなく、カラーコード(つまり、[[36m[[K[[m[[K)が含まれています。これは、--color=alwaysを使用しているためです。しかし、grepコマンドに色が必要であり、区切り文字を空白行にする必要があります(さらに処理するため)

これら2つの条件をどのように組み合わせることができますか?

12
Martin Vegter

GREP_COLORS環境変数を使用すると、一致のタイプごとに特定の色を制御できます。 man grepは、変数の使用法を説明しています。

次のコマンドは色付きの一致を出力しますが、グループを区切る行には何も出力せず、空白行のみを出力します。 odをパイプ処理すると、試合の前後に色がエスケープされますが、グループの分離では\n\nのみが表示されます。

GREP_COLORS='ms=01;31:mc=01;31:sl=:cx=:fn=35:ln=32:bn=32:se=' grep --group-separator="" --color=always -A5

seコンポーネントの設定を解除すると、グループセパレータでの色の印刷が抑制されます。

上記の例ではGREP_COLORSのデフォルト値をすべて使用しているため、以下も機能します。

GREP_COLORS='se=' grep --group-separator="" --color=always -A5

bashlike Shellを使用していない場合は、最初にGREP_COLORSをエクスポートする必要がある場合があります。

9
bsd

個人的には、grepではなくPerlを使用してこれを行います。特定のパターンを色で強調表示する小さなスクリプトがあります。

#!/usr/bin/env Perl
use Getopt::Std;
use strict;
use Term::ANSIColor; 

my %opts;
getopts('hsc:l:',\%opts);
    if ($opts{h}){
      print<<EoF; 
DESCRIPTION

$0 will highlight the given pattern in color. 

USAGE

$0 [OPTIONS] -l PATTERN FILE

If FILE is ommitted, it reads from STDIN.

-c : comma separated list of colors
-h : print this help and exit
-l : comma separated list of search patterns (can be regular expressions)
-s : makes the search case sensitive

EoF
      exit(0);
    }

my $case_sensitive=$opts{s}||undef; 
my @color=('bold red','bold blue', 'bold yellow', 'bold green', 
           'bold Magenta', 'bold cyan', 'yellow on_Magenta', 
           'bright_white on_red', 'bright_yellow on_red', 'white on_black');
## user provided color
if ($opts{c}) {
   @color=split(/,/,$opts{c});
}
## read patterns
my @patterns;
if($opts{l}){
     @patterns=split(/,/,$opts{l});
}
else{
    die("Need a pattern to search for (-l)\n");
}

# Setting $| to non-zero forces a flush right away and after 
# every write or print on the currently selected output channel. 
$|=1;

while (my $line=<>) 
{ 
    for (my $c=0; $c<=$#patterns; $c++){
    if($case_sensitive){
        if($line=~/$patterns[$c]/){
           $line=~s/($patterns[$c])/color("$color[$c]").$1.color("reset")/ge;
        }
    }
    else{
        if($line=~/$patterns[$c]/i){
          $line=~s/($patterns[$c])/color("$color[$c]").$1.color("reset")/ige;
        }
      }
    }
    print STDOUT $line;
}

パスにcolorとして保存すると、実行して目的の出力を取得できます。

grep --group-separator="" --color=never -A5 foo | color -l foo

そうすれば、スクリプトが一致に色を付け、grepに色を使用しないように指示して、この問題を回避できます。

5
terdon