일치하는 줄 앞의 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
blah1
5
blah2
blah3
8
9
답변2
이것은 펄 라인입니다:
$ 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
이 숫자 중 하나라도 범위를 벗어나면 실패할 수 있습니다.