Linux - grep & 정규 표현식

2021. 8. 8. 22:44Linux

이번 시간에는 grep과 grep에서 사용하는 정규표현식에 대해 배워보겠습니다

 

필터 : 모든 정보를 출력하는 것이 아닌 사용자가 원하는 정보만을 출력할 수 있도록 도와주는 역할을 합니다.

예를 들어 조회 명령어를 사용할 때 모든 내용을 출력하는 것이 아닌 디렉터리 파일만을 조회하고 싶거나 파일의 내용을 읽을 때 특정 단어가 들어가 있는 행만을 불러 오고 싶을 때 사용하는 것입니다.

 

grep : 파일 내에서 지정한 패턴과 일치하는 패턴이 있는 행을 출력 하고 싶을 때 사용하는 명령어입니다.

예를 들어 test 라는 파일에서 exam이라는 단어가 들어간 행을 출력 하고 싶을 때 사용 하는 명령어입니다.

grep {옵션} [찾고자 하는 단어] [파일명 or 검색하려는 위치]

{} : 생략 가능 [] : 필수

 

food라는 파일에서 exam 단어가 포함된 행을 찾겠다는 명령입니다.

 

 

exam이라는 단어를 현재 위치아래에 있는 모든 파일들로부터 찾겠다는 명령입니다.

 

옵션

-n : 행 번호가 같이 출력됩니다. 찾은 단어가 해당 파일의 몇번쨰 행에 입력된 단어인지 알려주는 것입니다.

 

 

-i : 대소문자 구분을 안합니다. test, Test, TEST 구분 없이 찾아준다는 것입니다

 

 

-l : 찾고자 하는 단어가 하나라도 있으면 그 파일의 이름을 출력해줍니다.

 

 

-w : 특정한 단어만을 찾을 때 사용합니다. test라는 단어를 찾으려고 하면 testfood, asstest 와 같은 단어가 아닌 test 앞뒤에 아무런 문자가 없는 단어만을 찾습니다.

 

 

이번에는 grep 명령어를 통해 검색에 도움을 주는 정규 표현식을 배워보겠습니다.

정규 표현식 : 특정한 규칙, 패턴을 가진 문자열의 집합을 검색하는데 사용합니다.

정규 표현식은 특수문자들을 사용하는 메타문자들과 문자 그대로를 사용하는 리터럴 문자들로 구성됩니다.

메타문자는 ^, $, *, [] 와 같은 문자들이고 리터럴 문자는 문자 그대로인 a,b,c,d 등을 의미합니다.

장규 표현식은 크게 기본 정규 표현식(BRE)과 확장 정규 표현식(ERE)로 구분됩니다.이들의 차이점은 메타문자와 관련이 있습니다. 기본 정규 표현식의 메타문자들은 ^, $, ., [], [^]와 같이 구분하고 이것을 제외한 다른 문자들은 리터럴 문자로 인식됩니다. 반면 확장 정규 표현식은 기본 정규 표현시의 메타문자에 ( ), { }, ?, 등이 추가됩니다. 지금부터 정규 표현식의 메타문자들을 공부 해보겠습니다. 메타 문자는 쉘의 확장에 사용되므로 확장 방지를 위해 따옴표로 묶어서 사용하는 것이 정확한 결과를 얻는 방법입니다.제가 연습한 예제들은 간단한 예제들이라 따옴표를 사용하지 않았으나 메타 문자 사용할 때 따옴표를 사용하는 습관을 가지는 것이 좋습니다.

 

1. 기본 정규 표현식 

- ^ : 행의 시작 지시자 : ^test는 test로 시작하는 모든 행을 출력합니다.  

- $ : 행의 끝 지시자 :  test$는 test로 끝나는 모든 행을 출력합니다.  

 

 

- . : 하나의 문자와 대응 : t..t는 t로 시작해서 t로 끝나는 총 4개의 문자로 이루어진 문자열을 포함하고 있는 모든 행을 출력합니다.

 

 

- [] : [] 안에 문자중 어느 하나라도 매칭되는 모든 행을 출력합니다. tes[n,v,f]인 경우 tesn, tesv, tesf 단어가 하나라도 있는 행들을 출력합니다.

 

 

- [^] : [^] 안에 문자 중 하나도 매칭되지 않는 모든 행을 출력합니다.

 

 

2. 확장 정규 표현식

기본 정규 표현식에서 사용하는 메타문자에 ( ), { }, ? + | 가 추가된다고 말했었습니다.

( ), { }는 BRE에서 사용하려면 백슬래시 \ 를 함께 사용해야지만 메타문자로 인식됩니다. 하지만 ERE에서는 메타문자 앞에 백슬래시를 사용하면 리터럴 문자로 인식을 합니다.

 

- | : 파이프, 명령과 명령을 연결할 때 사용하는 특수 문자입니다.

여러 명령어를 사용할 때 첫 번째 명령의 결과를 다음 명령의 입력값으로 넘겨서 사용합니다.

여기서 사용하는 파이프는 연산 파이프라고 합니다.

 

- 얼터네이션(Alternation) : 수직 파이프 메타문자

이 파이프를 grep 와 함께 사용하면 확장 정규 표현식의 메타문자로 사용이 되며 수직 파이프 메타문자라고 합니다. 기존의 파이프 연산자와 헷갈리시면 안됩니다.

이 수직 파이프 문자는 '하나라도 일치하는 문자열을 찾아주는 역할'을 하는 메타문자입니다.

grep 'AAA|BBB' ./* 는 현재 위치에 있는 파일들로 부터 AAA 와 BBB 중 하나라도 일치하는, 하나라도 포함하고 있는 모든 행을 출력하라는 뜻입니다.

 

 

아무런 출력이 되지 않는 것을 볼 수 있습니다. 저희가 사용하고 있는 GNU 버전 리눅스에서 확장 정규 표현식을 사용하려면 grep에 -E 옵션을 사용해야 하기 때문입니다. grep -E 대신 egrep를 사용해도 됩니다

 

잘 출력이 되는 것을 볼 수 있습니다.

 

얼터네이션을 다른 정규 표현식과 사용 할때 ( )를 사용해서 구분해줘야합니다. 예시를 보시면 이해하시기 편하실 겁니다.

 

 

'^(test|010|exam)' 은 test, 010, exam으로 시작하는 파일 내용들을 찾아 주라는 표현식입니다. 하지만 ( )로 얼터네이션( | )과 정규표현식(^)을 구분하지 않았다면 다른 결과가 나왔을 겁니다.

 

'^test|010|exam' 은 test로 시작하고 010과 exam이 포함된 파일 내용들을 찾아주라는 표현식입니다. 

( ) 로 구분 한것과 안한 것의 차이를 확인 할 수 있었습니다.

 

- 수량 한정자 (?, *, +, { }) : 하나의 요소를 찾는 횟수를 지정하는 방법을 지원합니다.

- ? : 항목이 없거나 한번만 나타나는 경우에 사용합니다.

예를 들어 번호를 검색한다고 할떄, 다음과 같은 두가지 형식이 있을 수 있습니다.

1234-5678 이거나 010-1234-5678 010을 생략한 경우도 있고 사용한 경우도 있을 것입니다. 이때 ? 메타문자를 사용해서 010이 없거나 한번만 사용한 경우를 찾으라고 지정해줄 수 있는 것입니다.

[0-9] : 0에서 9중 하나라도 있으면 검색됩니다. 

^(?[0-9][0-9][0-9]-)?[0-9][0-9][0-9][0-9]-[0-9][0-9][0-9][0-9]

어디서부터 어디까지 할지 범위를 ?로 열고 닫아줘야합니다.

 

 

- * : 항목이 없거나 여러 번 나타나는 경우 사용합니다.

0개 이상이라고 생각하시면 됩니다. 

 

- + : 항목이 한 번 이상 나타나는 경우 사용합니다.

1개 이상이라고 생각하시면 됩니다.

 

 

이상한 점이 있습니다.  ?은 0개또는 1개 +은 1개 이상 *은 0개 이상이라고 말씀 드렸습니다.

app+ = app, appl,apple 등을 검색

app? = ap, app를 검색

app* = ap,app,appl,apple 등을 검색 해야합니다.

하지만 결과는 다르게 나오고 있습니다.

app+ = app만을 검색, app? = ap, app를 검색, app* = apple만을 검색하고 있습니다.

app?를 제외하고는 다른것을 볼 수 있습니다. 이점에 대해서는 제가 다음시간에 더 공부해서 알아오겠습니다.

 

- { } : 검색 횟수의 최소와 최댓값을 지정할 때 사용합니다.

{n} : n번 일치하는 행 검색

{n, m} : n번 이상 m번 미만으로 일치하는 행 검색

{n, } : n번 이상 일치하는 행 검색

{, m} : m번 미만 일치하는 행 검색

 

번호를 검색할 때 주로 사용합니다.

010-1234-5431와 같은 번호를 검색한다고 생각해보겠습니다.

그럼 위의 번호를 검색하기 위해서는 다음과 같이 사용합니다.

[0-9][0-9][0-9]-[0-9][0-9][0-9][0-9]-[0-9][0-9][0-9][0-9]

 

[0-9]만 사용하면 숫자를 모두 검색합니다. 번호 형식에 맞는 숫자를 검색하기 위해서는 [0-9][0-9][0-9]-[0-9][0-9][0-9][0-9]-[0-9][0-9][0-9][0-9]와 같이 입력해야 합니다.

 

 

하지만 너무 긴것을 볼 수 있습니다. 이를 아까 배운 간격 정규 표현식으로 줄여보겠습니다.

[0-9]{3}-[0-9]{4}-[0-9]{4}으로 훨씬 간단해졌습니다. 

 

 

같은 결과를 출력하는 것을 볼 수 있습니다.

 

이상으로 grep과 정규표현식에 대해 공부해보았습니다. 다음 시간에는 파일내용이 아닌 원하는 파일들을 검색할 수 있는 명령어에 대해 공부 해보겠습니다.

 

 

 

다음 내용

Linux - locate & find

 

 

'Linux' 카테고리의 다른 글

Linux - 프로세스 - 1 (정의)  (0) 2021.08.16
Linux - locate & find  (0) 2021.08.10
Linux - 마운트  (0) 2021.08.07
Linux - 패키지 관리 도구 rpm & yum  (0) 2021.08.02
Linux - 권한(permission)(3)  (0) 2021.08.01