一致した行のn行前、一致した行、一致した行からn行目を印刷します。

一致した行のn行前、一致した行、一致した行からn行目を印刷します。

一致した行の前の n 行目、一致した行、一致した行から n 行目 (n は 2 より大きい) を印刷します。

ここに私のデータ ファイルの例を示します (以下の行番号はデータの一部ではなく、識別のためだけのものです)。私が検索しているパターンは、ファイル内の「blah」ですexample.txt

$ cat example.txt 
 1. a
 2. b
 3. c
 4. d
 5. blah
 6. e
 7. f
 8. g
 9. h
 10. blah
 11. i
 12. f
 13. g
 14. h

そして、出力は次のようになります:

 1. b
 2. blah
 3. g
 4. f
 5. blah
 6. g

ワンライナーを提案してください!

答え1

awk -vn=3 '/blah/{print l[NR%n];print;p[NR+n]};(NR in p);{l[NR%n]=$0}'

これは重複がないことを前提としています。重複がある場合は、関連するすべての行が印刷されますが、複数回印刷される可能性があり、必ずしも入力と同じ順序であるとは限りません。

これを回避するには、次のように記述します。

awk -vn=3 '/blah/{p[NR-n]p[NR]p[NR+n]};(NR-n in p){print l[NR%n]}
  {l[NR%n]=$0};END{for(i=NR-n+1;i<=NR;i++)if (i in p) print l[i%n]}'

次のような入力の場合:

1
2
3
4
blah1
5
6
blah2
blah3
7
8
9
10

最初のものは次のようになります:

2
blah1
blah1
blah2
blah2
5
blah3
8
9

2 番目は次のように出力されます:

2
blah1
5
blah2
blah3
8
9

答え2

以下は Perl のワンライナーです:

$ perl -ne '$n=3;push @lines,$_; END{for($i=0;$i<=$#lines;$i++){
  if ($lines[$i]=~/blah/){
    print $lines[$i-$n],$lines[$i],$lines[$i+$n]}}
 }' example.txt 
b
blah
g
f
blah
g

周囲の行の数を変更するには、 ( は希望する数)に変更します。$n=3;一致するパターンを変更するには、を に変更します。$n=NNif ($lines[$i]=~/blah/)if ($lines[$i]=~/PATTERN/)

数字が実際にファイルの一部である場合は、次のようにすることができます。

$ perl -ne '$n=3;push @lines,$_; END{for($i=0;$i<=$#lines;$i++){
      if ($lines[$i]=~/blah/){
        print $lines[$i-$n],$lines[$i],$lines[$i+$n]}}
     }' example.txt | perl -pne 's/\d+/$./'
1. b
2. blah
3. g
4. f
5. blah
6. g

答え3

以下は @terdon の回答と似ていますが、メモリには 2n+1 の関連行のみが保持されます。

my $n = shift;
my $pattern = shift;
my @lines = ("\n") x (2*$n+1);
while (<>) {
    shift @lines;
    push @lines, $_;
    if ($lines[$n] =~ m/$pattern/) {
        print $lines[0], $lines[$n], $lines[-1];
    }
}

次のように実行します:perl example.pl 3 blah example.txt

答え4

あまり効率的ではありません。grep を使用して行番号を取得し、sed を使用して行番号を出力します。

for n in `grep -n blah example.txt | sed -e s/:.*//`
do
    sed -n -e "$[$n-3]p" -e "$[$n]p" -e "$[$n+3]p" example.txt
done

結果的に

 2. b
 5. blah
 8. g
 7. f
 10. blah
 13. g

いずれかの数値が範囲外になった場合は、おそらく失敗するでしょう。

関連情報