grep의 -A -B -C 스위치(앞과 뒤에 몇 줄 인쇄)에 대한 대안이 있습니까?

grep의 -A -B -C 스위치(앞과 뒤에 몇 줄 인쇄)에 대한 대안이 있습니까?
grep -A 2 -B 3 

grep 문자열 뒤에 2줄, 그 앞에 3줄을 인쇄합니다.

grep -C 3

처음 3줄과 마지막 3줄을 인쇄합니다.

안타깝게도 grep제가 사용하고 있는 제품은 이러한 옵션을 지원하지 않습니다. 이를 시뮬레이션하는 데 사용할 수 있는 대체 명령이나 스크립트가 있습니까? sed/// 쉘 스크립트를 사용하시겠습니까 awk?perl

답변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

관련 정보