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
의 반대의미) 매치가 발생하지 않은 파일 이름만 출력한다.
-m
NUM, --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 구분자는 :
이고 컨텍스트는 -
로 구분된 접두어가 출력되며, 그룹간의 구분은 --
으로 출력된다.
-A
NUM, --after-context=
NUM: 매칭된 라인 뒤로 NUM 줄만큼 추가 표시한다.
-B
NUM, --before-context=
NUM: 매칭된 라인 앞으로 NUM 줄만큼 추가 표시한다.
-C
NUM, --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
와 같은 옵션이다.
-D
ACTION, --devices=
ACTION: 장치를 찾았을 때 액션을 정의한다. 기본적으로 read이며, skip으로 변경가능하다.
-d
ACTION, --directories=
ACTION: 디렉토리를 찾았을 때 액션을 정의한다.1
그외 옵션
--line-buffered
: 라인 버퍼링을 사용한다. 성능 저하가 있을 수 있다.
--mmap
: 가능하다면 read
대신 mmap
시스템 콜을 사용한다.
-U
, --binary
: 파일을 이진으로 취급한다.
정규식
grep은 기본적으로 기본정규식, 확장정규식, 펄 정규식을 이해할 수 있으며 GNU grep은 확장 정규식과 기본정규식을 구분하지 않는다. 그외의 구현에서는 일반 정규식은 확장 정규식보다 덜 파워풀하며, ?{}|
등의 특별한 의미를 지니는 문자들을 이스케이핑해야 인식한다.
grep 정규식에 대한 내용은 따로 정리하든지 해야겠다.
- 디렉토리를 일반 파일처럼 읽는다는게 무슨 뜻인지 모르겠다. ↩