2012-12-19 3 views
1

알고 있습니다. -A-B-C grep 키워드와 관련된 문맥을 표시하는 데 사용할 수 있습니다.다른 grep 키워드에 다른 문맥을 표시 하시겠습니까?

내 질문은 다른 키워드에 다른 컨텍스트를 표시하는 방법?

예를 들어, 내가 어떻게 원숭이 개가 고양이 -A 5, -B 4-C 1을 보여 않습니다

egrep -A3 "cat|dog|monkey" <file> 
// this just show 3 after lines for each keyword. 
+0

의 가능한 복제본 거기 sed를 사용하는 아주 좋은 해결책이 있습니다. – RaveTheTadpole

답변

1

내가 하나 그렙 전화와 함께 할 수있는 방법이 있다고 생각하지 않지만, 당신은 출력 각 변수에 대해 한 번 그렙을 통해 그것을 실행하고 연결할 수 :

var=$(grep -n -A 5 cat file)$'\n'$(grep -n -B 4 dog file)$'\n'$(grep -n -C 1 monkey file) 
var=$(sort -un <(echo "$var")) 

지금 echo "$var"이 같은 생산됩니다 (: 접두사는 패턴과 정확히 일치하는 줄을 나타내며 접두사 --A-B 및/또는 -C 옵션 때문에 줄이 포함됨을 나타냅니다). 줄 번호 및 컨텍스트 표시기 .

내가 지금까지 줄 번호를 포함시킨 이유는 한 문장에서이 작업을 수행했다면 보았을 결과의 순서를 유지하는 이유입니다. 정확한 일치하는 라인 '접두사를 잘라이 한 번을 통해 전달

var=$(cut -d: -f2- <(echo "$var") | cut -d- -f2-) 

을 다시 문맥이 일치 잘라 : 당신은 그들을 큰하지만, 당신이 그들을 잘라 다음 줄을 사용할 수없는 경우 좋아하는 경우 '접두사.

pretty? 아니. 그러나 그것은 효과적이다. 이 같은

+0

+1하지만 일치하는 줄에 "-"가 포함되어 있고 변수 나 에코가 필요하지 않으면 여러 줄이기가 실패하고 다른 실패가 발생할 수 있습니다. 나는 이것이 다음과 같이 할 것이라고 생각한다 : $ (f = "file"; grep -n -A 5 cat "$ f"; grep -n -B 4 개 "$ f"; grep -n -C 1 monkey "$ f ") | 정렬 -un | sed -r 's/^ [^ : -] + [: -] //''. 방금 "f"를 도입하여 동일한 파일 이름을 여러 번 지정하지 않아도됩니다. –

+0

필자는'-f2-'를 지정 했으므로 줄 바꿈이 괜찮을 것이라고 생각했습니다. 줄의 끝에서 2 번째 줄을 출력하도록 알려줍니다. 그래서 나머지가'-' 또는':'를 포함하더라도 여전히 괜찮을 것입니다.(내가 잘못 생각하고 있니?)하지만 그렇지 않으면 나는 당신의 의견에 동의하고 파일 이름을 반복하는 대신 $ f를 사용하는 것을 좋아한다. – nullrevolution

+0

'cut -d :와 관련된 문제 | cut -d-'는 그 문자 중 하나를 포함하는 줄이 잘리지 않을 것이라는 것입니다. 예를 들어 '7 : 반올림'과 '9-it 's 10 : 30'과 같이 2 줄이 있고'반올림 '과'10 : 30 '으로 인쇄하고 싶다면' 업 '과'30 ' –

1

grep 그렇게하지 않습니다 난 두려워. 다른 도구를 사용해야합니다. 아마도 당신 자신의 프로그램을 작성하십시오.

0

뭔가를 할 것이다 :

awk ' 
    BEGIN{ ARGV[ARGC++] = ARGV[1] } 

    function prtB(nr) { for (i=FNR-nr; i<FNR;  i++) print a[i] } 
    function prtA(nr) { for (i=FNR+1; i<=FNR+nr; i++) print a[i] } 

    NR==FNR{ a[NR]; next } 

    /cat/ { print; prtA(5) } 
    /dog/ { prtB(4); print } 
    /monkey/ { prtB(1); print; prtA(1) } 

' file 

검사에게 수학 함수에서 루프에. 원숭이와 개를 포함하는 줄을 어떻게 처리할지 말하지 않았습니다.

편집 :

awk -v cxts="cat:0:5\ndog:4:0\nmonkey:1:1" ' 
    BEGIN{ 
     ARGV[ARGC++] = ARGV[1] 
     numCxts = split(cxts,cxtsA,RS) 
     for (i=1;i<=numCxts;i++) { 
     regex = cxtsA[i] 
     n = split(regex,rangeA,/:/) 
     sub(/:[^:]+:[^:]+$/,"",regex) 
     endA[regex] = rangeA[n] 
     startA[regex] = rangeA[n-1] 
     regexA[regex] 
     } 
    } 

    NR==FNR{ 
     for (regex in regexA) { 
     if ($0 ~ regex) { 
      start = NR - startA[regex] 
      end = NR + endA[regex] 
      for (i=start; i<=end; i++) { 
       prt[i] 
      } 
     } 
     } 
     next 
    } 

    FNR in prt 

' file 
: 여기에서 일치하는 주위 최대 컨텍스트를 인쇄하고 명령 행에서 컨텍스트를 지정할 수 및 위의 저렴하고 쾌활한 솔루션으로 많은 메모리를 사용하지 않을 것입니다 안된 솔루션입니다

cxts 변수에서 검색된 패턴을 RS 값이 기본값 인 개행 문자로 분리하십시오.

관련 문제