Linux 환경에서 grep
명령어는 파일 내에서 특정 문자열이나 패턴을 찾아 일치하는 행을 표시하는 데 사용되는 강력한 도구입니다. 단순히 파일 검색뿐만 아니라, 다른 명령어의 결과를 파이프라인으로 연결하여 처리하는 데에도 유용합니다. 이 글에서는 grep
명령어의 다양한 활용법을 자세히 살펴보겠습니다.
grep 명령어의 유래
grep
명령어는 유닉스 시스템에서 매우 중요한 위치를 차지하고 있습니다. 그 이유는 다음과 같습니다. 첫째, grep
은 텍스트 검색에 있어 매우 실용적입니다. 둘째, 다양한 옵션을 제공하여 사용자 요구에 맞는 세밀한 검색이 가능합니다. 셋째, 특정 요구 사항을 해결하기 위해 개발되었습니다. 초기에는 ed
편집기에서 정규식 검색 기능을 분리하여 작은 유틸리티 프로그램으로 제작되었습니다.
켄 톰슨은 ed
편집기의 정규 표현식 검색 기능을 분리하여 텍스트 파일 검색에 사용되는 소규모 프로그램을 만들었습니다. 그의 상사인 벨 연구소의 더글러스 맥일로이는 톰슨에게 리 맥마흔의 문제를 설명했습니다.
맥마흔은 연방주의자 논문의 저자를 텍스트 분석을 통해 판별하고자 했으며, 텍스트 파일에서 구절이나 문자열을 찾는 도구를 필요로 했습니다. 톰슨은 자신이 만들었던 도구를 일반적인 유틸리티로 개선하여 grep
이라는 이름으로 제공했습니다. grep
은 ed
명령어인 “g/re/p” (전역 정규식 검색)에서 유래했습니다.
grep
의 탄생 비화에 대한 이야기는 이 링크에서 브라이언 커니건과의 대화에서 확인할 수 있습니다.
기본적인 grep 검색
파일 내에서 특정 문자열을 찾으려면 명령어 라인에 검색어와 파일 이름을 입력하면 됩니다.
결과로 일치하는 행이 표시됩니다. 대부분의 배포판에서는 grep
명령어에 별칭이 설정되어 있어 일치하는 텍스트가 강조 표시됩니다.
alias grep='grep --colour=auto'
여러 줄에서 일치하는 결과를 확인해 보겠습니다. 예를 들어, 로그 파일에서 “평균”이라는 단어를 검색해 봅시다. 단어의 대소문자가 확실하지 않으므로 -i(대소문자 무시) 옵션을 사용합니다.
grep -i Average geek-1.log
일치하는 모든 행이 나타나며, 각 행에서 일치하는 텍스트는 강조되어 표시됩니다.
-v
(반전) 옵션을 사용하면 일치하지 않는 행만 표시할 수 있습니다.
grep -v Mem geek-1.log
일치하지 않는 행이므로 강조 표시는 없습니다.
grep
은 결과를 출력하지 않고, 단지 반환값만으로 검색 결과를 알려줄 수도 있습니다. 반환값 0은 문자열이 발견되었음을 의미하고, 1은 발견되지 않았음을 의미합니다. $?
특수 매개변수를 사용하여 반환값을 확인할 수 있습니다.
grep -q average geek-1.log
echo $?
grep -q wdzwdz geek-1.log
echo $?
재귀적인 grep 검색
중첩된 디렉토리와 하위 디렉토리를 검색하려면 -r
(재귀) 옵션을 사용합니다. 파일 이름 대신 검색을 시작할 경로를 지정해야 합니다. 아래 예시에서는 현재 디렉토리(“.”) 및 모든 하위 디렉토리를 검색합니다.
grep -r -i memfree .
출력에는 일치하는 각 줄의 디렉토리 및 파일 이름이 표시됩니다.
-R
(재귀적 참조 해제) 옵션을 사용하면 grep
이 심볼릭 링크를 따라가도록 할 수 있습니다. 이 예시에는 `/home/dave/logs` 디렉토리를 가리키는 `logs-folder`라는 심볼릭 링크가 있습니다.
ls -l logs-folder
-R
옵션을 사용하여 마지막 검색을 다시 실행해 보겠습니다.
grep -R -i memfree .
이제 심볼릭 링크를 따라 해당 링크가 가리키는 디렉토리까지 grep
이 검색합니다.
전체 단어 검색
기본적으로 grep
은 검색어가 문자열 내에 포함되어 있어도 일치하는 것으로 간주합니다. 예를 들어 “free”라는 단어를 검색해 보겠습니다.
grep -i free geek-1.log
결과에는 “free” 문자열이 포함된 행이 나타나지만, 별도의 단어인 경우는 없습니다. 예를 들어 “MemFree” 문자열의 일부로 포함되어 있습니다.
grep
이 별도의 “단어”와만 일치하도록 하려면 -w
(단어 regexp) 옵션을 사용하십시오.
grep -w -i free geek-1.log
echo $?
이번에는 “free”라는 검색어가 파일에 별도의 단어로 나타나지 않으므로 결과가 없습니다.
다중 검색어 사용
-E
(확장 정규식) 옵션을 사용하면 여러 단어를 검색할 수 있습니다. (-E 옵션은 grep
의 egrep
버전과 같습니다.)
다음 명령어는 “average”와 “memfree”라는 두 가지 검색어를 검색합니다.
grep -E -w -i "average|memfree" geek-1.log
각 검색어에 대해 일치하는 모든 행이 표시됩니다.
완전한 단어가 아니어도 되지만 완전한 단어일 수도 있는 여러 검색어를 검색할 수도 있습니다.
-e
(패턴) 옵션을 사용하면 명령어 라인에서 여러 검색어를 사용할 수 있습니다. 정규식 대괄호 기능을 사용하여 검색 패턴을 만들 수 있습니다. 대괄호 안에 있는 문자 중 하나와 일치하도록 grep
에게 지시합니다. 아래 예시에서는 grep
이 “kB” 또는 “KB”와 일치하게 됩니다.
grep -e "mem[kK]B" -e Average geek-1.log
두 문자열 모두 일치하며, 일부 행에는 실제로 두 문자열이 모두 포함되어 있습니다.
정확한 줄 일치
-x
(정규식 줄) 옵션은 전체 줄이 검색어와 정확히 일치하는 줄만 찾습니다. 로그 파일에서 한 번만 나타나는 날짜 및 시간 스탬프를 검색해 보겠습니다.
grep -x "20-Jan--06 15:24:35" geek-1.log
일치하는 단일 행을 찾아 표시합니다.
반대로, 일치하지 않는 행만 표시할 수도 있습니다. 이는 설정 파일 등을 확인할 때 유용합니다. 주석은 유용하지만, 실제 설정을 찾기 어려울 때가 있습니다. 다음은 `/etc/sudoers` 파일의 예시입니다.
다음 명령을 사용하여 주석 줄을 효과적으로 필터링할 수 있습니다.
sudo grep -v "https://www.wdzwdz.com/496056/how-to-use-the-grep-command-on-linux/#" /etc/sudoers
훨씬 쉽게 구문 분석이 가능해집니다.
일치하는 텍스트만 표시
일치하는 전체 줄이 아닌, 일치하는 텍스트만 보고 싶을 때가 있습니다. -o
(일치하는 경우만) 옵션을 사용하면 됩니다.
grep -o MemFree geek-1.log
이제 검색어와 일치하는 텍스트만 표시됩니다.
grep으로 계산하기
grep
은 텍스트 관련 작업뿐 아니라 숫자 정보도 제공할 수 있습니다. 파일 내에서 검색어가 몇 번 나타나는지 알고 싶다면 -c
(count) 옵션을 사용할 수 있습니다.
grep -c average geek-1.log
grep
은 해당 파일에 검색어가 240번 나타난다고 알려줍니다.
-n
(줄 번호) 옵션을 사용하면 grep
이 일치하는 각 줄의 줄 번호를 표시하도록 할 수 있습니다.
grep -n Jan geek-1.log
각 일치하는 줄의 줄 번호가 줄의 시작 부분에 표시됩니다.
표시되는 결과 수를 제한하려면 -m
(최대 개수) 옵션을 사용합니다. 아래에서는 출력을 5개의 일치하는 줄로 제한합니다.
grep -m5 -n Jan geek-1.log
문맥 추가
일치하는 각 행과 함께 몇 줄의 추가 (일치하지 않는) 행을 표시하는 것이 유용할 때가 많습니다. 이는 관심 있는 행을 구별하는 데 도움이 될 수 있습니다.
일치하는 줄 뒤에 일부 줄을 표시하려면 -A
(컨텍스트 이후) 옵션을 사용합니다. 이 예시에서는 세 줄을 요구합니다.
grep -A 3 -x "20-Jan-06 15:24:35" geek-1.log
일치하는 줄 이전의 일부 줄을 보려면 -B
(컨텍스트 이전) 옵션을 사용합니다.
grep -B 3 -x "20-Jan-06 15:24:35" geek-1.log
일치하는 줄 전후의 줄을 모두 포함하려면 -C
(컨텍스트) 옵션을 사용합니다.
grep -C 3 -x "20-Jan-06 15:24:35" geek-1.log
일치하는 파일 표시
검색어가 포함된 파일의 이름을 보려면 -l
(일치하는 파일) 옵션을 사용합니다. 예를 들어, `sl.h` 헤더 파일에 대한 참조가 포함된 C 소스 코드 파일을 찾으려면 다음 명령을 사용하십시오.
grep -l "sl.h" *.c
일치하는 줄이 아니라 파일 이름이 나열됩니다.
반대로, 검색어가 포함되지 않은 파일을 찾을 수도 있습니다. -L
(일치하지 않는 파일) 옵션이 이를 수행합니다.
grep -L "sl.h" *.c
줄의 시작과 끝
grep
이 줄의 시작이나 끝에 있는 일치 항목만 표시하도록 강제할 수 있습니다. "^"
정규식 연산자는 줄의 시작과 일치합니다. 다음은 실제로 로그 파일 내의 모든 줄에 공백이 포함되지만, 첫 번째 문자로 공백이 있는 줄을 검색하는 예시입니다.
grep "^ " geek-1.log
첫 번째 문자로 공백이 있는 줄(줄 시작 부분)이 표시됩니다.
줄의 끝을 일치시키려면 "$"
정규식 연산자를 사용하십시오. 아래에서는 “00”으로 끝나는 줄을 검색합니다.
grep "00$" geek-1.log
디스플레이에 “00”이 마지막 문자로 포함된 행이 표시됩니다.
grep과 파이프 사용
물론, grep
으로 입력을 파이프하고 grep
의 출력을 다른 프로그램으로 파이프할 수 있습니다. 즉 파이프 체인 중간에 grep
을 배치할 수 있습니다.
C 소스 코드 파일에서 “ExtractParameters” 문자열이 있는 모든 행을 확인하고 싶다고 가정해 보겠습니다. 결과가 많을 것이므로 출력을 `less`로 파이프합니다.
grep "ExtractParameters" *.c | less
출력이 `less`에서 표시됩니다.
이렇게 하면 파일 목록을 탐색하고 `less`의 검색 기능을 사용할 수 있습니다.
grep
의 출력을 wc
로 파이프하고 -l
(lines) 옵션을 사용하면 “ExtractParameters”가 포함된 소스 코드 파일의 줄 수를 셀 수 있습니다. (물론 grep -c
(count) 옵션을 사용할 수 있지만, 여기서는 grep
에서 파이프를 사용하는 방법을 보여주기 위한 예시입니다.)
grep "ExtractParameters" *.c | wc -l
다음 명령은 `ls`의 출력을 grep
으로 연결하고, grep
의 출력을 `sort`로 연결합니다. 현재 디렉토리의 파일을 나열하고, “Aug” 문자열이 포함된 파일을 선택한 후 파일 크기별로 정렬합니다.
ls -l | grep "Aug" | sort +4n
분석해 보겠습니다.
ls -l
: `ls`를 사용하여 긴 형식의 파일 목록을 생성합니다.grep "Aug"
: `ls` 목록에서 “Aug”가 포함된 행을 선택합니다. (이름에 “Aug”가 포함된 파일도 찾을 수 있습니다.)sort +4n
: `grep`의 출력을 네 번째 열(파일 크기)으로 정렬합니다.
결과적으로 8월에 수정된 모든 파일의 정렬된 목록(파일 크기의 오름차순)을 얻을 수 있습니다.
결론: grep, 더 많은 기능과 활용
grep
은 매우 강력한 도구입니다. 1974년에 개발된 이후로, 여전히 널리 사용되고 있습니다. grep
은 필요하며, 더 나은 대안이 없기 때문에 강력한 성능을 유지하고 있습니다.
grep
을 정규식과 결합하면 더욱 강력한 검색이 가능합니다.