콘텐츠로 건너뛰기
Home » grep 간단 사용법

grep 간단 사용법🔍

grep은 주어진 파일(들)이나 표준입력에서 주어진 패턴과 매칭되는 라인들을 필터링하여 출력해주는 유틸리티로 여러 파일에서 특정한 문자열을 한 번에 찾을 수 있게하는 도구이다.

grep의 사촌쯤 되는 fgrep, egrep도 있는데 이들은 각각 grep의 -F, -E 옵션으로 통합되었으며 현재는 오래된 스크립트에서 호출하는 상황을 위해호환성 유지 측면으로만 남겨져 있다고 생각하면 된다.

사용법

grep은 여러 옵션과 더불어서 패턴과 대상 파일을 인자로 주어 실행할 수 있다. 대상 파일은 공백으로 분리한 여러 개의 파일일 수 있으며, 와일드카드를 포함하거나 디렉토리일 수 있다.

# 일반패턴을 사용하여 검색하는 경우
grep [OPTIONS] PATTERN [FILE...]
# 정규식이나 파일의 내용을 패턴으로 사용하는 경우
grep [OPTIONS] -e PATTERN | -f FILE [FILE...]

이 때 패턴에 정규식을 사용하는 경우 -e 옵션을 사용한다. 패턴을 파일로부터 읽어서 찾으려는 경우 -f 파일 옵션을 사용한다.

옵션

비교자 선택

패턴을 해석하는 방식을 변경할 수 있다. 기본적으로 유닉스 기본 정규식을 사용하며 확장 정규식이나 펄 정규식등을 사용하는 옵션이 있다.

-E, --extened-regexp: 주어진 패턴을 확장 정규식으로 해석한다. 이 옵션은 egrep 을 사용하는 것과 동일한 결과를 만들어낸다.

-F --fixed-string : 주어진 패턴을 고정 문자열로 해석한다. 이는 개행문자로 나뉜 문자열 집합이 될 수 있으며, 그 중 한 라인과 매치하면 매칭된 것으로 간주한다.

-G, --basic-regexp: 주어진 패턴을 기본 정규식으로 해석한다.

-P, --perl-regexp: 주어진 패턴을 펄 정규식으로 해석한다. 다만 100% 호환은 아니고 일부 펄 정규식의 기능은 구현되지 않았으니 주의한다.

매칭 컨트롤

grep이 매치해서 출력하는 결과는 패턴이 매치되는 문자열을 포함하는 각 라인이다. 아래의 옵션들은 매치의 방식을 결정한다.

-e PATTERN, --regexp=PATTERN : 주어진 패턴을 정규식 패턴으로 사용한다. 여러 개의 옵션을 연이어 사용하면 하나의 패턴으로 결합된다.

-f FILE, --file=FILE : 패턴을 지정한 파일로부터 한 번에 한줄씩 읽어들인다. 빈 파일은 제로 패턴으로 취급하며 어느 라인에도 매치되지 못한다.

-i, --ignore-case : 대소문자 구분을 하지 않고 매칭한다.

-w, --word-regexp : 전체 “단어”가 주어진 패턴에 매치하는 경우에 해당한다. 예를 들어 “cp” 라는 패턴은 “memcpy”에 기본적으로 매치되지만, 이 옵션이 들어간 경우에는 매치되지 않는다. 정규식 패턴의 앞뒤로 \b를 준것과 유사하게 작동한다.

-v, --invert-match: 매치 결과를 뒤집는다. 즉 매치되지 않는 행만 출력한다.

-x, --line-regexp: 라인 전체가 주어진 패턴에 일치해야 한다.

출력 제어

-c, --count: 기본 출력을 무시하고 출력된 행의 개수만 센다. 즉 파일별로 파일의 이름과 매칭되는 라인 수만 표시한다. (출력될 행의 개수를 세므로 만약 -v옵션과 함께 쓰이면 매치되지 않은 행의 개수가 표시된다.)

--color[=WHEN]: 매치된 부분 (및 행번호, 파일이름 등)에 색상을 칠한다. 이 옵션은 never, auto, always 중 하나가 될 수 있다. (일부 플랫폼에서는 지원되지 않는 경우가 있음)

-l, --files-with-match: 매치가 발생한 파일 이름만 출력한다.

-L, --files-without-match: (-l의 반대의미) 매치가 발생하지 않은 파일 이름만 출력한다.

-mNUM, --max-count=NUM: 각각의 파일을 NUM 개 만큼의 매치가 발생하면 더 이상 읽지 않는다.

-o, --only-matching: 라인 전체를 출력하는 대신에 매치된 부분만 출력한다.(이 때 파일 이름은 붙는다)

-q, --quiet, --silent: 아무것도 출력하지 않는다. 매치가 발생하면 정상 출력코드를 내고 바로 종료하며 찾지 못한 경우에는 비정상 종료코드를 리턴한다.

-s, --no-messages: 읽을 수 없거나 존재하지 않는 파일 등에 대한 에러 메시지를 출력하지 않는다.

출력 행 제어

-n, --line-number: 매치된 행 번호도 출력한다.

-b, --byte-offset: 각 결과에 대해서 파일 시작점으로부터 매치 시작점의 오프셋을 표시한다.

-h, --no-filename: 파일명을 생략한다.

-H, --with-filename: 각 매치에 파일명을 표시한다. 이는 디폴트로 적용된다.

-T, --initial-tab: 행이 탭으로 시작할 때 탭을 올바르게 출력한다.

컨텍스트 라인 컨트롤

grep은 결과 출력 시 매칭되는 라인 뿐만 아니라 그 앞뒤의 문맥을 파악할 수 있도록 몇 줄을 추가로 출력할 수 있다. 이 옵션은 -o가 주어지면 무시된다. 이 때 매칭된 라인의 prefix 구분자는 : 이고 컨텍스트는 -로 구분된 접두어가 출력되며, 그룹간의 구분은 --으로 출력된다.

-ANUM, --after-context=NUM: 매칭된 라인 뒤로 NUM 줄만큼 추가 표시한다.

-BNUM, --before-context=NUM: 매칭된 라인 앞으로 NUM 줄만큼 추가 표시한다.

-CNUM, --context=NUM: 앞 뒤로 NUM 줄씩만큼 추가 표시한다.

## -nA2 옵션을 주었을 때 출력예시
$ grep -nA2 fmap *.hs
InteractWith.hs:17:        myFunction = fmap toUpper
--
parser.hs:8:    fmap f p = Parser $ \str ->
parser.hs-9-        case runParser p str of
parser.hs-10-             []        -> []
--
parser.hs:84:-- nat = fmap read (many digit)
parser.hs-85-
parser.hs-86-spc :: Parser ()
--
pp.hs:7:  fmap f p = Parser $ \str ->
pp.hs-8-        case runParser p str of
pp.hs-9-          [] -> []

파일/디렉토리 선택

-include=GLOB: 주어진 영역에 대해서만 찾는다.

--exclude=GLOB: 특정 이름/패스는 생략한다.

-R, -r, --recursive: 하위 디렉토리들을 모두 찾는다.

-a, --text : 이진 파일도 텍스트 처럼 취급한다. --binary-files=text와 같은 옵션

--binary-files=TYPE: 이진 파일을 특정한 타입처럼 취급한다. 기본적으로 binary로 이는 경고문만 출력한다. without-match는 그냥 넘어간다. text는 텍스트 파일처럼 매치를 시도한다.

--exclude-from=FILE: 파일에 정의한 각 GLOB에 대해서는 제외한다.

--exclude-dir=DIR: DIR 패턴에 맞는 디렉토리들을 제외한다.

-I: 이진파일을 생략한다. --binary-files=without-match와 같은 옵션이다.

-DACTION, --devices=ACTION: 장치를 찾았을 때 액션을 정의한다. 기본적으로 read이며, skip으로 변경가능하다.

-dACTION, --directories=ACTION: 디렉토리를 찾았을 때 액션을 정의한다.1

그외 옵션

--line-buffered: 라인 버퍼링을 사용한다. 성능 저하가 있을 수 있다.

--mmap: 가능하다면 read 대신 mmap 시스템 콜을 사용한다.

-U, --binary: 파일을 이진으로 취급한다.

정규식

grep은 기본적으로 기본정규식, 확장정규식, 펄 정규식을 이해할 수 있으며 GNU grep은 확장 정규식과 기본정규식을 구분하지 않는다. 그외의 구현에서는 일반 정규식은 확장 정규식보다 덜 파워풀하며, ?{}| 등의 특별한 의미를 지니는 문자들을 이스케이핑해야 인식한다.

grep 정규식에 대한 내용은 따로 정리하든지 해야겠다.


  1. 디렉토리를 일반 파일처럼 읽는다는게 무슨 뜻인지 모르겠다.