일치하는 줄 앞의 n번째 줄, 일치하는 줄과 일치하는 줄의 n번째 줄을 인쇄합니다.

일치하는 줄 앞의 n번째 줄, 일치하는 줄과 일치하는 줄의 n번째 줄을 인쇄합니다.

일치하는 줄 앞에 n번째 줄을 인쇄하고, 일치하는 줄과 "n"이 2보다 큰 일치하는 줄의 n번째 줄을 인쇄하고 싶습니다.

다음은 내 데이터 파일의 예입니다(아래 줄 번호는 데이터의 일부가 아니며 단지 식별용임). 내가 검색하는 패턴은 파일에서 "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
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=N하십시오 . N일치하는 패턴을 변경하려면 if ($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

해당 숫자 중 하나라도 범위를 벗어나면 실패할 수 있습니다.

관련 정보