2017-09-18 2 views
1

grep을 일반적인 명령 줄에서 사용할 수 있습니다.Unix 쉘 스크립트에서 grep -C를 사용할 수 없습니다.

grep "ABC" Filename -C4 

이렇게하면 일치하는 패턴 라인의 위와 아래 4 줄의 원하는 출력을 얻을 수 있습니다.

그러나 유닉스 쉘 스크립트에서 같은 명령을 사용하면 패턴 위와 아래의 줄을 grep 할 수 없습니다.

+1

'uname -srv'의 출력으로 Q를 업데이트하십시오. 나는 당신이 SunOS (또는 많은 다른 것들)의 구버전을 사용하고 있다고 확신한다.'- [ABC]'옵션은 사용할 수없는 곳이다. 그러나 cmd 라인에서 작동하므로'which grep'을 입력하고 스크립트에서'/ path/to/ABCgrep/grep'과 같은 전체 경로를 사용하거나 PATH 설정을'export PATH = "와 같이 무시해야합니다/경로/to/ABCgrep/grep : $ PATH "'. 행운을 빕니다. – shellter

+1

파일 이름 앞에 옵션을 넣으십시오 :'grep -C4 "ABC"Filename ".그것도 작동하지 않는다면 쉘 스크립트가 실행하는 grep과는 다른 grep을 실행 중입니다 - 사용하는'grep '을위한 올바른 경로를 찾아 스크립트에서 사용해야합니다. '-A','-B' 및'-C' 옵션은 GNU 확장입니다. o/s 명령은 그들을 지원하지 않을 수 있습니다. 사용중인 플랫폼을 확인하지 못했습니다. Linux 인 경우 문제가되지 않지만 Solaris 또는 AIX 또는 HP-UX 인 경우 문제가 될 수 있습니다. 당신이 리눅스 태그를 사용하지 않았기 때문에 아마도 여러분이 사용하고있는 리눅스가 아닌 것 같습니다. –

답변

0

나는 당신을 가정합니다 내가 -A4-B4를 사용하는 경우 -C4

결과는 유사하다 : 그것은 나에게 grep을 열 수 없다고 할 수없는 결국 패턴이 일치하는 유일한 선으로 출력하고 오류를주고있다 GNU 확장자가없는 이식 가능한 POSIX 솔루션이 필요합니다 (-C NUM, -A NUM-B NUM은 패턴 및/또는 파일 이름 뒤에 오는 인수와 마찬가지로 모두 GNU 임).

POSIX grepPOSIX awk 수 있습니다. 이것은 예를 들면 다음과 같이 호출 될 수있다. grepC -C4 "ABC" Filename (, 그것은 "grepC"라는 가정은 실행, 그리고에 당신의 $PATH) :

#!/bin/sh 

die() { echo "$*\nUsage: $0 [-C NUMBER] PATTERN [FILE]..." >&2; exit 2; } 

CONTEXT=0 # default value 

case $1 in 
    -C ) CONTEXT="$2"; shift 2 ;;  # extract "4" from "-C 4" 
    -C*) CONTEXT="${1#-C}"; shift ;;  # extract "4" from "-C4" 
    --|-) shift ;;      # no args or use std input (implicit) 
    -* ) [ -f "$1" ] || die "Illegal option '$1'" ;; # non-option non-file 
esac 

[ "$CONTEXT" -ge 0 ] 2>/dev/null || die "Invalid context '$CONTEXT'" 
[ "$#" = 0 ] && die "Missing PATTERN" 

PATTERN="$1" 
shift 

awk ' 
    /'"$PATTERN"'/ { 
    match='$CONTEXT' 
    for(i=1; i<=CONTEXT; i++) if(NR>i) print last[i]; 
    print 
    next 
    } 
    match { print; match-- } 
    { for(i='$CONTEXT'; i>1; i--) last[i] = last[i-1]; last[1] = $0 } 
' "[email protected]" 

이것은 치명적인 오류 함수로 die을 설정 한 후 인수에서 컨텍스트의 원하는 라인을 찾습니다 (중 -C NUMBER를 또는 -CNUMBER) 지원되지 않는 옵션에 오류가 있습니다 (파일이 아닌 경우).

컨텍스트가 숫자가 아니거나 패턴이없는 경우 다시 심각한 오류가 발생합니다.

그렇지 않으면 패턴을 저장하고 멀리 이동 한 다음 awk에 파일 ("[email protected]")을 넘겨주는 나머지 옵션을 예약합니다.

  1. 일치 패턴 자체 :

    이 AWK 호출에서 세 스탠자가 있습니다. 이 경우 awk -v을 통해 가져올 경우 올바로 동작하지 않을 수있는 $PATTERN 변수를 통합하기 위해 문자열의 작은 따옴표 부분을 끝내야합니다. 일치하면 문맥의 줄 수를 match 변수에 저장하고 last 해시에 저장된 이전 줄을 반복하여 (충분히 가지고 있다면) 인쇄합니다. 그런 다음 다른 두 스탠자를 평가하지 않고 다음 줄로 건너 뜁니다.

  2. 일치하는 항목이있는 경우 다음 몇 줄의 문맥이 필요합니다. 이 스탠자가이를 인쇄 할 때 카운터를 감소시킵니다. 새로운 일치 (이전 절)가 해당 개수를 재설정합니다.
  3. 일치시 리콜을 위해 이전 라인을 저장해야합니다. 이것은 우리가 염려하는 문맥의 수를 반복하고 last 해시에 저장합니다. 현재 줄 ($0)은 last[1]에 저장됩니다.
관련 문제