bash 쉘에서 파일의 섹션을 grep하는 방법 디

어떤 string1의 발생과 어떤 string2의 (N 번째) 발생 사이의 줄을 어떻게 grep 할 수 있습니까?

예 :

파일에 행이있는 경우 :

에이

기음

이자형

에프


기음
이자형

선을 굵은 체로 만들고 싶습니다 (B로 시작하고 E로 끝나는 선).

grep을 사용하여이 작업을 수행 할 수 있습니까? 또는 다른 유닉스 명령 줄 도구?



답변

grep 이 작업에 적합하지 않은 경우 하나의 도구를 “위로”올려야합니다.

sed -n '/^B/,/^E/p' infile

산출:

B
C
D
E
B
C
E

N 번째 요구 사항에 관해서는, 한 도구를 “위로”즉 awk로 다시 이전하는 것이 가장 쉽다고 생각합니다.

awk '/^B/ { f = 1; n++ } f && n == wanted; /^E/ { f = 0 }' wanted=2 infile

산출:

B
C
E

깃발 f 언제 설정 되나요? /^B/ 때 발생하고 설정되지 않은 /^E/ sed 표기법이 작동하는 것과 같은 방식으로 진행됩니다. n 얼마나 많은 블록이 통과되었는지, 언제 f == 1 && n == wanted 가 true이면 기본 블록이 실행됩니다 ( { print $0 } ).


답변

@ Thor ‘s sed 명령은 구타 될 수 없지만 다음 명령으로 perl 스크립트 괄호 안에 질문의 일부를 처리하려고합니다. “… (N 번째) 발생 …”.

용법:

./script <start-regex> <end-regex> [N]

질문에있는 파일의 예 :

$ ./script "B" "E" < examplefile
B
C
D
E
B
C
E

$ ./script "B" "E" 2 < examplefile
B
C
D
E
F
G
B
C
E

어떤 오류 검사도 없으며 스크립트는 욕심이 없습니다, 즉 A B C D E E FB C D E N = 1로 grep 될 것입니다.


#!/usr/bin/perl

if ($ARGV[2] != "") { $n = $ARGV[2] } else { $n = 1 }
$begin_str = $ARGV[0];
$end_str = $ARGV[1];

while(<STDIN>) {
  if($_ =~ $begin_str) { $flag=1 }             # beginning of match, set flag
  if($_ =~ $end_str && $flag eq 1) { $i++ }    # i-th occurence of end string

  if($i eq $n) {                               # end of match after n occurences of end string
    $flag=2;
    $i=0;
  }

  if ($flag ge 1) {                            # append currrent line to matching part
    $out.=$_;
  }

  if($flag eq 2) {                             # after detection of end of match, print complete match
    print $out;
    # print "---\n";                           # separator after a match
    $out="";
    $flag=0;
  }

}