1

-A -B -Cgrep キーワードの前後のコンテキストを表示するために使用できることはわかっています。

私の質問は、異なるキーワードで異なるコンテキストを表示するにはどうすればよいですか?

たとえば、-A 5猫、-B 4犬、-C 1猿を表示するにはどうすればよいですか。

egrep -A3 "cat|dog|monkey" <file> 
// this just show 3 after lines for each keyword. 
4

3 に答える 3

2

単一のgrep呼び出しでそれを行う方法はないと思いますが、変数ごとに1回grepを実行して出力を連結できます:

var=$(grep -n -A 5 cat file)$'\n'$(grep -n -B 4 dog file)$'\n'$(grep -n -C 1 monkey file)
var=$(sort -un <(echo "$var"))

これecho "$var"で、単一のコマンドから取得したものと同じ出力に加えて、行番号とコンテキスト インジケーターが生成されます (:接頭辞は、パターンに正確に一致した行を示し、接頭辞はand/orオプション-のために含まれている行を示します) .-A -B-C

これまでに行番号を含めた理由は、1 つのステートメントでこれを行うことができた場合に表示される結果の順序を維持するためです。気に入った場合は素晴らしいですが、そうでない場合は、次の行を使用してそれらを切り取ることができます。

var=$(cut -d: -f2- <(echo "$var") | cut -d- -f2-)

これは、完全に一致する行のプレフィックスをカットするために一度通過し、次にコンテキスト一致のプレフィックスをカットするためにもう一度通過します。

かわいい?番号。しかし、それは機能します。

于 2012-12-19T14:58:40.037 に答える
1

私はgrepそれをしないと思います。別のツールを使用する必要があります。おそらく、独自のプログラムを作成します。

于 2012-12-19T04:53:38.063 に答える
0

このような何かがそれをするでしょう:

awk '
   BEGIN{ ARGV[ARGC++] = ARGV[1] }

   function prtB(nr) { for (i=FNR-nr; i<FNR;     i++) print a[i] }
   function prtA(nr) { for (i=FNR+1;  i<=FNR+nr; i++) print a[i] }

   NR==FNR{ a[NR]; next }

   /cat/    { print; prtA(5) }
   /dog/    { prtB(4); print }
   /monkey/ { prtB(1); print; prtA(1) }

' file

関数のループの計算を確認してください。たとえば、猿と犬を含む行をどのように処理するかについては言いませんでした。

編集:これは、一致するものの周りに最大のコンテキストを出力し、コマンドラインでコンテキストを指定できるようにし、上記の安価で陽気なソリューションほど多くのメモリを使用しない、テストされていないソリューションです:

awk -v cxts="cat:0:5\ndog:4:0\nmonkey:1:1" '
   BEGIN{
      ARGV[ARGC++] = ARGV[1]
      numCxts = split(cxts,cxtsA,RS)
      for (i=1;i<=numCxts;i++) {
         regex = cxtsA[i]
         n = split(regex,rangeA,/:/)
         sub(/:[^:]+:[^:]+$/,"",regex)
         endA[regex]   = rangeA[n]
         startA[regex] = rangeA[n-1]
         regexA[regex]
      }
   }

   NR==FNR{
      for (regex in regexA) {
         if ($0 ~ regex) {
            start = NR - startA[regex]
            end   = NR + endA[regex]
            for (i=start; i<=end; i++) {
               prt[i]
            }
         }
      }
      next
   }

   FNR in prt

' file

cxts変数で検索されたパターンを、RS値(デフォルトでは改行)で区切ります。

于 2012-12-19T15:39:57.267 に答える