Shell - grep 명령어

24 March 2016

grep 명령은 한 개 혹은 여러개의 파일의 내용에서 문자 패턴을 검색한다. 검색 패턴은 따옴표로 묶인 문자열이거나 공백이 없는 한 단어여야 한다. 검색에 성공하면 파일의 해당 line을 화면에 출력한다. 참고로 grep은 global / regular expression / print의 약자이다.

$ cat file1.txt
Hello, World
123
abcdefg

$ cat file2.txt
grep test
hello world
12345

$ grep llo file1.txt 
Hello, World

$ grep llo file1.txt file2.txt file3.txt	# 파일 여러개에 대해서도 검색 가능
file1.txt:Hello, World
file2.txt:hello world

grep 명령어의 옵션

option 기능
-b block. 검색 결과의 각 line 앞에 디스크 블록 번호를 표시함.
-c count. 일치한 line을 출력하지 않고, 일치한 line의 갯수만 출력.
-h 여러 파일을 검색할 때, 일치하는 줄의 맨 앞에 파일명이 출력되는데 이 파일명을 출력하지 않음.
-i ignore. 대소문자 무시.
-l 일치하는 line이 존재하는 파일명을 나열. 하나의 파일에 여러 line이 일치하더라도 파일명은 한 번만 출력됨.
-L 일치하는 line이 존재하지 않는 파일명을 나열.
-n 파일 내의 줄 번호를 각 line의 앞에 붙여서 출력.
-v 패턴과 일치하지 않는 줄을 모두 출력.
-w 문자 패턴을 하나의 단어로 검색. \<문자패턴\> 과 동일함.

참고) -w 옵션 등에서 말하는 단어란? 연속된 알파벳의 앞과 뒤에 공백 혹은 구두점 혹은 개행문자가 오는 것이다.

grep 명령어의 반환 값

  • 패턴을 찾으면 종료 상태로 0 반환
  • 패턴을 찾지 못하면 종료 상태로 1 반환
  • 파일 자체가 존재하지 않으면 종료 상태로 2 반환

bash shell 기준으로 echo $?을 실행해보면 종료 상태를 확인할 수 있다.

참고) sed, awk 등 다른 패턴 검색 관련 유틸리티에서는 검색의 성공 여부에 대해서는 종료 상태값을 반환하지 않고, 명령의 문법 오류에 대해서만 오류 보고를 한다. 즉 종료 상태값을 봐서는 패턴을 찾았는지 찾지 못했는지를 알 수 없다.

grep 명령어와 pipe

파일 뿐 아니라 표준 입력이나 pipe로도 입력 받을 수 있다. 어떤 명령의 출력을 grep의 입력으로 pipe로 연결하면, 해당 명령의 결과 중 원하는 패턴의 내용만 화면에 출력할 수 있다.

$ ps -ef | grep tomcat

ps -ef 명령은 현재 시스템에서 실행중인 모든 프로세스를 보여준다. 이 결과가 grep 명령으로 보내지고, tomcat을 포함하고 있는 모든 line이 출력된다.

grep 명령어와 정규표현식

문자 패턴에 정규표현식 메타문자를 사용할 수 있다.

메타문자 기능
^ line의 맨 앞
$ line의 맨 뒤
. 아무 문자 1개
* 아무 문자 0개 이상
[abc] or [a-z] 괄호 안의 문자 집합 중 한 개와 일치
[^abc] or [^a-z] 괄호 안의 문자 집합에 없는 글자와 일치
\< 단어의 시작
\> 단어의 끝
\(문자\) 괄호 안의 문자를 capture. capture된 부분은 레지스터에 저장되어 \1, \2, \3..으로 참조할 수 있다.
a\{m\} 문자 a를 m번 반복
a\{m,\} 문자 a를 m번 이상 반복
a\{m,n\} 문자 a를 m번 이상 n번 이하 반복

egrep - extended grep

egrep 명령어는 grep에서 제공하는 정규표현식 뿐 아니라 몇몇의 추가적인 메타문자를 지원한다. 단 grep에서 제공하는 메타문자 중 문자 캡처 \(\), 반복자 \{\}은 지원하지 않는다. egrep에서 사용 가능한 확장된 정규표현식 메타문자는 다음과 같다.

  • + : + 기호 앞의 문자가 1개 이상. 3+은 3, 333, 3333 등과 일치. [a-z]+ove는 aove, approve, love 등과 일치.
  • ? : ? 기호 앞의 문자가 0개 혹은 1개.
  • a|b : a 또는 b. cat|dog|tiger 같은 형태도 사용 가능.
  • () : 문자 그룹. (ab)+는 ab, abab, ababab 등과 일치한다. (do|Do)g는 dog, Dog와 일치한다.

참고) [dD]og 또한 dog, Dog와 일치한다. 문자 집합 [dD]은 한 개의 문자만 일치시킬 때 사용, 문자 그룹 (dog|Dog)은 한 개 이상의 문자를 일치시킬 때 사용한다.

fgrep - fast / fixed grep

fgrep 명령어는 기본적으로 grep과 동일하게 동작하나, 정규표현식 메타문자를 사용하지 않는다. 그냥 문자 그 자체로만 취급한다.

리눅스에서의 grep - GNU grep

리눅스에서는 grep과 동일한 기능을 가지면서 훨씬 뛰어난 GNU 버전 grep을 사용한다. 또한 grep 명령어만으로 egrep, fgrep 기능을 사용할 수 있다.

option 기능
-E egrep과 동일. 확장된 정규표현식 메타문자 사용 가능.
-F fgrep과 동일. 모든 정규표현식 메타문자 사용하지 않음.

확장된 정규표현식 메타문자 앞에 역슬래시(\)를 붙이면 -E 옵션 없이도 egrep 기능을 수행한다. \?, \+, \{\}, \|, \(\)

$ grep -E '(dog|cat)' file
$ egrep '(dog|cat)' file
$ grep '\(dog\|cat\)' file

위의 세 명령어는 모두 동일하다.

리눅스의 grep에서 사용 가능한 정규표현식 메타문자

메타문자 기능
\w [a-zA-Z0-9]
\W [^a-zA-Z0-9]
\b단어\b 단어 범위 지정. \<단어\> 대신 사용 가능.

또한 리눅스의 egrep, grep -E 에서는 capture 문자 \(..\)와 문자 반복자 a\{m,n\} 앞에 역슬래시를 붙이지 않아도 된다.

메타문자 기능
(문자) 괄호 안의 문자를 capture. capture된 부분은 레지스터에 저장되어 \1, \2, \3..으로 참조할 수 있다.
a{m} 문자 a를 m번 반복
a{m,} 문자 a를 m번 이상 반복
a{m,n} 문자 a를 m번 이상 n번 이하 반복

리눅스의 grep에서 사용 가능한 유용한 옵션들

option 기능
-r recursive. 재귀적으로 하위 디렉토리를 탐색. rgrep 으로도 사용 가능.
-숫자 context. 일치된 줄에서 앞/뒤로 n줄을 함께 출력. -2 는 -C 로도 쓸 수 있다.
-A 숫자 after context. 일치된 줄 뒤의 n줄을 함께 출력
-B 숫자 before context. 일치된 줄 앞의 n줄을 함께 출력
-x line 전체와 정확하게 일치하는 줄만 출력
-q quiet. 아무것도 출력 하지 않음.
-s silent. 존재하지 않거나 읽을 수 없는 파일에 대한 오류 메시지를 출력하지 않는다.
-e –regexp=pattern 으로도 사용 가능. 패턴에 있는 모든 문자를 그대로 처리해서, 패턴의 맨 앞에 dash(-)가 있어도 이를 옵션으로 판단하지 않도록 한다.
Git 유용한 환경 설정 및 alias 셋팅 node.js heapdump 생성하기