우리는 원하는 결과에 빠르게 도달하기 위해 키워드를 기반으로 검색하곤 합니다.
웹 페이지나 에디터같은 익숙한 GUI환경에서는 Ctrl + F 또는 Cmd + F 를 통해 검색하는 것은 늘상 있는 일이죠.
하지만 개발을 하다보면 때로는 터미널 환경에서 검색을 해야하는 상황도 발생하고는 합니다.
이때에는 우리가 GUI환경에서 사용하던 방법으로 검색하기에는 한계가 있습니다.
그럼 터미널에서는 어떻게 찾으면 좋을까요?
바로 이 때 사용하면 좋은 것이 grep 이라는 명령어입니다.
grepGNUFreeBSD 2가지 버전이 존재하는데, 버전마다 옵션에 조금 차이가 있으므로 실습 결과가 조금 다를수도 있습니다.
본 글에서는 Mac(BSD) 기준으로 작성해보도록 하겠습니다.
그럼 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 [-옵션] 패턴 [파일]

iksflow@iksflow src % 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 를 여러개 사용하기
iksflow@iksflow src % 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 를 사용해 파일에 정의된 패턴을 사용하기
iksflow@iksflow src % grep -in -f patterns.txt expression.txt
28:phone: 010-1234-5678

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

# -e 와 -f를 동시에 사용하기
iksflow@iksflow src % 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 패턴]

iksflow@iksflow src % 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

      iksflow@iksflow src % grep -c mail expression.txt
      2
      iksflow@iksflow src % grep --count mail expression.txt
      2

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

  • -i, --ignore-case

      iksflow@iksflow src % grep -i date expression.txt
      # Date: 2020-05-05
      iksflow@iksflow src % grep date expression.txt

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

  • -n, --line-number

      iksflow@iksflow src % 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

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

  • -v, --invert-match

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



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

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

      iksflow@iksflow src % grep 'B$' expression.txt
      Memory size is 32GiB
      Disk is 512 GB

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

  • --color

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

  • -A n

      iksflow@iksflow src % 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

      iksflow@iksflow src % 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

      iksflow@iksflow src % 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 을 같이 사용한 결과와 일치합니다.

참고

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

'Etc > Linux' 카테고리의 다른 글

[Shell] awk 명령어로 컬럼 단위 조건 검색하기  (0) 2022.06.07
[Linux]터미널 화면 지우는 방법  (0) 2020.09.16