grepの-A -B -Cスイッチ(前後に数行印刷)に代わるものはありますか?

grepの-A -B -Cスイッチ(前後に数行印刷)に代わるものはありますか?
grep -A 2 -B 3 

grep文字列の後に2行、その前に3行を印刷します。

grep -C 3

最初の3行と最後の3行を印刷します。

残念ながらgrep、私が使用している製品はこれらのオプションをサポートしていません。これをシミュレートするために使用できる代替コマンドまたはスクリプトはありますか?sed///シェルスクリプトを使用しますかawkperl

答え1

やや醜い方法は

grep -v pattern file >file.tmp; diff -c file.tmp file

または、-cコンテキスト-C NUM行をNUM次に置き換えます。ただし、追加の出力が生成されます。 (/をdiffサポートすると、よりきれいになります。)-u-U NUM

//これを行うdiff方法はまだ残っていますが、かなり見苦しいです。一方、PerlをサポートしていないシステムにはPerlもない可能性があります。-c-C-udiff-c

答え2

確認するPerlだけが必要で、インクルード-Aとgrepに似たオプションが必要-Bです。-Cgrepの構文ではなくPerlの正規表現構文を使用し、検索するファイルを選択する方法もまったく異なります。-f使用するときは、そのオプションを試してみることもできます(実際には何も検索せずに検索するファイルを印刷します)。

次のようにインストールできます。単一スクリプト非コアモジュールは必要ありません。これを~/binディレクトリ(または書き込み権限を持つPATHの他の場所)に入れて、実行可能であることを確認chmodしてください。

答え3

この単純なPerlスクリプトはgrep -Aある程度シミュレートします。

#!/usr/bin/perl

$pattern=shift; #patthern to search
$lines=shift; # number of lines to print

$n = 0;
while (<>) {
  $n = $lines if /$pattern/; # reset counting
  if ($n) { print; $n-- } # print if within
  $n = 0 if eof; # don't leak across file boundaries
}

スクリプトを読み、使用できるようにusingステートメントを追加できます。)

USAGE:    $./grep-A.pl <pattern> <numLines> <filename> 

答え4

シミュレーション-Bは、一致する線が互いに直接接続されているときに問題が発生するため、非常に厳しいことがわかりました。これにより、どんな種類のシングルパスファイル検索もほとんど許可されません。

私は次のような近似を試みてこれを実現しました。

perl -pe 'if(/search_term/) {print foreach @A; print ">"; $B=4}; shift @A if push(@A, $_)>7; $_ = "" unless ($B-- > 0);' target_file

これは、最初の段落で説明されている注意事項を除いて、grep -A7 -B3とほぼ同じことを正しく行います。

この問題に対する別の(単一ファイル)解決策は、Perlを使用してsedにコマンド文字列を提供することです。

sed -n `perl -pe '$_=(/search_term/?sprintf("%d,%dp;", $.-3,$.+4):"")' file` file

関連情報