Skip to content

grep으로 원하는 내용을 검색해보자!

우리는 원하는 결과에 빠르게 도달하기 위해 키워드를 기반으로 검색하곤 합니다.
익숙한 GUI환경에서는 Ctrl + F 를 통해 검색하는 것은 늘상 있는 일이죠.
그럼 터미널에서는 어떻게 찾으면 좋을까요?
바로 grep 이라는 명령어를 통해 원하는 결과만을 얻을 수 있습니다.
grepGNUFreeBSD 2가지 버전이 존재하는데, 버전마다 옵션에 조금 차이가 있으므로 실습 결과가 조금 다를수도 있습니다.
그럼 grep은 무엇이고 어떻게 사용하는지 알아볼까요?

1. grep 이란?

grep파일의 내용이나 명령어의 출력 결과에서 정의한 옵션 및 패턴에 해당되는 문자열이 포함된 라인을 찾아내는 명령어입니다.
그래서 설정 파일이나 로그 파일처럼 내용이 많은 경우에 grep을 활용한다면 원하는 내용을 금방 찾을 수 있습니다.
앞서 언급한 패턴은 간단한 문자열 및 정규 표현식을 의미합니다.
간단한 문자열을 활용해 탐색하는 것만으로도 충분히 활용할 수 있지만, grep을 충분히 활용하기 위해선 정규 표현식 을 알아두는 편이 좋습니다.
정규 표현식에 대한 내용만으로도 책 한 권은 족히 나오기에, 본 글에서는 활용하기 쉬운 몇 가지와 옵션을 소개하려고 합니다.
참고로 grepglobal|regular expression|print의 앞 글자를 따서 만든 단어라고 합니다.

2. grep의 사용 방법

grep의 사용법은 크게 2가지가 있습니다.
첫 번째는 파일의 내용을 대상으로 패턴에 맞는 문자열을 탐색하는 것이고, 두 번째는 명령어의 출력 결과를 받아서 패턴에 맞는 문자열을 찾는 것입니다.
그럼 간단한 실습을 통해 grep의 문법에 대해 알아보겠습니다.
문법에서 복수로 선택할 수 있는 항목은 대괄호[]로 표시했습니다.
실습을 위해 expression.txt라는 대상 파일과 pattern.txt라는 패턴 파일을 만들겠습니다.

  • expression.txt

    ==================== Regular Expression ====================
    #===========================================#
    # Date: 2020-05-05 # Author: Sung # Description: regular expression test file
    
    #===========================================#
    Today is 12-Sep-2021. Current time is 6:04PM.
    This is an example file for testing regular expressions.
    This example file includes control characters.
    
    # System Information CPU model is Intel(R) Core(TM) i7-8665U CPU @ 1.90GHz Memory size is 32GiB Disk is 512 GB IP Address is 192.168.35.7
    # Help Do you have any questions? or Do you need any help? If you have any questions, Please send a mail to the email below.
    # Contacts e-mail: theiksflow@gmail.com phone: 010-1234-5678
    

  • patterns.txt

    phone
    

2.1 grep [-옵션] 패턴 [파일]

$ grep -i mail expression.txt
If you have any questions, Please send a mail to the email below.
e-mail: theiksflow@gmail.com

가장 기본적인 활용 방법으로 대상 파일에서 1개의 패턴을 사용해 탐색을 하는 방식입니다.
찾으려는 내용이 복잡하지 않은 경우 활용하기 좋습니다.
-i 옵션은 ignore-case를 의미하며 대소문자 일치 여부를 확인하지 않습니다.

2.2 grep [-옵션] [-e 패턴 | -f 파일] [파일]

-e 를 여러개 사용하기

$ grep -ni -e 'mail' -e 'phone' expression.txt
24:If you have any questions, Please send a mail to the email below.
27:e-mail: theiksflow@gmail.com
28:phone: 010-1234-5678

검색 대상에 여러 개의 패턴을 한 번에 적용시키고 싶을 때는 -e 패턴을 여러 개 정의할 수 있습니다.
예시에 사용된 -n 옵션은 탐색한 내용이 몇번째 라인에 위치하는지 표시합니다.

-f 를 사용해 파일에 정의된 패턴을 사용하기

$ grep -in -f patterns.txt expression.txt
28:phone: 010-1234-5678

일회성 작업이라면 -e 패턴 을 사용하는 것으로 충분할 것입니다.
그런데 만약 패턴을 사용해야 검색하는 일이 빈번하다면 어떨까요?
매번 손으로 입력하는 것은 상당히 귀찮은 작업으로 느껴질 것입니다.
이런 경우 미리 사용할 패턴을 파일에 저장해놓고 재사용할 수 있다면 더 편하겠죠?
-f 파일 을 활용하면 패턴이 정의된 파일을 불러와서 사용할 수 있습니다.

-e-f를 동시에 사용하기

$ grep -in -e 'mail' -f patterns.txt expression.txt
24:If you have any questions, Please send a mail to the email below.
27:e-mail: theiksflow@gmail.com
28:phone: 010-1234-5678

참고로 위 처럼 둘 다 사용하는것도 가능합니다.

2.3 명령어 | grep [옵션] [패턴 | -e 패턴]

$ cat expression.txt | grep -i -e 'mail' -f patterns.txt
24:If you have any questions, Please send a mail to the email below.
27:e-mail: theiksflow@gmail.com
28:phone: 010-1234-5678

마지막은 정말 많이 사용되는 방법 중 하나인 명령어 | grep 입니다.
실행 결과를 출력하는 타입의 명령어라면 파이프(|)grep을 사용해서 패턴에 맞는 결과만 가져올 수 있습니다.
대표적인 명령어로는 cat이 있습니다.
grep 또한 실행 결과가 출력이므로 grep | grep처럼 활용하는 것도 가능합니다!

3. grep의 옵션

  • -c, --count : 패턴과 일치하는 라인 개수를 출력합니다.
  • -i, --ignore-case : 대소문자를 구분하지 않습니다.
  • -n, --line-number : 패턴과 일치하는 라인 번호를 표시합니다.
  • -v, --invert-match : 패턴과 일치하지 않는 라인을 출력합니다.
  • --color : 패턴과 일치하는 텍스트에 색을 입힙니다.
  • -A n, --after-context : 패턴과 일치하는 라인의 이후를 n만큼 더 보여줍니다.
  • -B n, --before-context : 패턴과 일치하는 라인의 이전을 n만큼 더 보여줍니다.
  • -C n, --context : 패턴과 일치하는 라인의 전후를 n만큼 더 보여줍니다.
    (-C 1-A 1 -B 1 과 같습니다.)

위 내용은 grep을 사용할 때 알아두면 좋은 옵션들을 나열한 것입니다.
그럼 옵션을 사용하면 어떤 결과가 나오는지 실습을 통해 살펴보겠습니다.

-c, --count

이전에 보았던 grep 의 결과와는 달리 숫자만 보입니다.
-c 옵션은 패턴과 일치하는 라인 수를 출력하는데, 문자열 개수가 아니라는 점을 반드시 기억해야 합니다.

$ grep -c mail expression.txt 2
$ grep --count mail expression.txt 2

-i, --ignore-case

앞서 여러번 보았던 -i옵션으로 문자열의 대소문자를 구분하지 않습니다. 사용하지 않는 경우 결과가 다른 것을 확인할 수 있습니다.

$ grep -i date expression.txt # Date: 2020-05-05
$ grep date expression.txt

-n, --line-number

-n은 패턴과 일치하는 라인의 라인 넘버를 표시합니다.

$ grep -n '^#' expression.txt 5:#===========================================# 6:# Date: 2020-05-05 7:# Author: Sung 8:# Description: regular expression test file 9:#===========================================# 17:# System Information 23:# Help 27:# Contacts

-v, --invert-match

$ grep -v '^#' expression.txt | grep -v '^$'
====================
Regular Expression
====================

Today is 12-Sep-2021.
Current time is 6:04PM.
This is an example file for testing regular expressions.    This example file includes control characters.
CPU model is Intel(R) Core(TM) i7-8665U CPU @ 1.90GHz
Memory size is 32GiB
Disk is 512 GB
IP Address is 192.168.35.7
Do you have any questions? or Do you need any help?
If you have any questions, Please send a mail to the email below.
e-mail: theiksflow@gmail.com
phone: 010-1234-5678

-v 옵션은 패턴과 일치하는 라인을 제외한 결과를 출력합니다.
그 결과 주석과 빈 라인이 사라진 깔끔한 내용을 얻을 수 있었습니다.
여기서 잠깐 패턴에서 사용한 정규표현식 문자에 대해 알아볼까요?
^는 라인의 시작을 의미하고 $는 라인의 끝을 의미합니다.
^#와 같이 사용한다면 라인의 시작이 #문자인 경우를 탐색하게 되어 다음과 같은 결과를 얻을 수 있습니다.

$ grep '^#' expression.txt
#===========================================#
# Date: 2020-05-05
# Author: Sung
# Description: regular expression test file
#===========================================#
# System Information
# Help
# Contacts


$ grep 'B$' expression.txt
Memory size is 32GiB
Disk is 512 GB

그래서 ^$은 시작과 끝에 어떠한 문자도 들어있지 않은 빈 라인을 의미합니다.
이러한 성질을 이용해서 주석이나 빈 라인을 제거한 내용을 확인할 수 있습니다.
참고로 중간에 Today is 12-Sep-2021. 위로 빈 라인이 있는 이유는 공백문자가 포함되어 있기 때문입니다.

그리고 B$B로 끝나는 라인을 탐색하게 되고 다음과 같은 결과가 나오게 됩니다.

--color--color는 패턴과 일치하는 부분을 하이라이팅해서 보여줍니다.

-A n

$ grep -A 1 'mail' expression.txt 
If you have any questions, Please send a mail to the email below.

--
e-mail: theiksflow@gmail.com
phone: 010-1234-5678

패턴과 일치하는 부분의 이후 라인을 n만큼 더 보여줍니다.
눈여겨 볼 특징으로는 구분자 --가 삽입된다는 점인데요, 이후 소개할 -B-C도 동일한 특징을 가지고 있습니다.

-B n

$ grep -B 1 'mail' expression.txt
Do you have any questions? or Do you need any help?
If you have any questions, Please send a mail to the email below.
--
# Contacts
e-mail: theiksflow@gmail.com

패턴과 일치하는 부분의 이전 라인을 n만큼 더 보여줍니다.

-C n

$ grep -C 1 'mail' expression.txt
Do you have any questions? or Do you need any help?
If you have any questions, Please send a mail to the email below.

--
--
# Contacts
e-mail: theiksflow@gmail.com
phone: 010-1234-5678

패턴과 일치하는 부분의 전후 라인을 n만큼 더 보여줍니다.
-A n, -B n 을 같이 사용한 결과와 일치합니다.

마무리

이번 글에서는 grep으로 원하는 내용을 검색하는 방법에 대해 알아보았습니다.
문자열을 찾아보았으니 파일을 찾는법도 알아둘 필요가 있겠죠?
그래서 다음 글에서는 파일을 찾는 명령어인 find에 대해 알아보고자 합니다.

참고

  • 처음 배우는 셸 스크립트 - 한빛미디어

작성자: 성승익

작성일: 2021-09-12