다시 시작하는 리눅스 #14 정규 표현식

최동민·2022년 12월 31일
0

Linux

목록 보기
23/25

리눅스를 사용하다 보면 많은 텍스트 파일을 다루게 된다. 이렇게 수많은 텍스트 파일을 다룰 때 중요한 기능이 특정 문자열 패턴을 검색하는 기능이다.

grep 명령어와 정규 표현식

문자열을 검색하는 명령어이다.
grep [옵션] <검색 패턴> <파일 이름>
grep<파일 이름>에서 <검색 패턴>에 일치하는 행을 출력한다.

-n 옵션은 행 번호를 출력한다. 파일에서 검색한 문자열의 위치를 파악하기 위해 사용된다.

대소문자를 구별하지 않고 검색할 때는 -i 옵션을 사용한다.
다음과 같이 기본 검색에는 아무것도 출력되지 않지만, 옵션을 적용하니 출력이 되었다.

-v 옵션을 사용하면 검색할 문자열이 나타나지 않는 행을 출력한다.
문자열 bash를 포함하지 않는 행을 출력하는 것.

다른 필터 명령어와 마찬가지로 grep 명령어도 파일을 지정하지 않으면 표준 입력을 읽는다.
ls 명령어의 출력 결과를 grep로 검색하는 식. 이처럼 다른 명령어의 실행 결과를 grep 으로 검색하는 방법을 자주 사용한다.

정규 표현식이란

grep에서는 일반적인 문자열 외에도 정규 표현식이라는 검색 패턴을 지정할 수 있다.
정규 표현식을 사용하면 조건에 일치하는 문자열 집합을 표현할 수 있다.
^는 행의 시작을 의미하기 때문에 cron으로 시작하는 문자열만을 출력한다.
위의 결과와는 사뭇 다르다.

여기서 정규 표현식을 '(작은따옴표)로 감싸주었는데, 이는 셸이 정규 표현식을 확장하지 않도록 하기 위해서이다. 이 외에도 *, {, }, $ 등의 기호가 특별한 의미로 사용된다. 이러한 문자를 메타 문자라 부르며 메타 문자의 대부분은 셸에서도 특별한 의미를 가진다. 가령 *는 셸에서 와일드카드로 해석되어 경로가 확장된다 하였다.
(정규 표현식을 작은따옴표로 감싸지 않으면 셸이 먼저 해석한다는 것)

임의의 문자를 지정하는 메타 문자

메타 문자 .(점)은 임의의 문자 하나를 의미한다.

다음과 같은 내용의 텍스트 파일 example.txt가 있다.

t에 이어 임의의 문자 하나가 있고 그 뒤에 st가 있는 문자열을 검색한다면

메타 문자 .을 한 번 더 쓴다면

메타 문자.은 기호도 포함한다.

임의의 문자가 아니라 점이라는 기호 자체를 검색하고 싶을 때는 \.라고 표시해야 한다. 메타 문자 앞에 \를 붙이면 이는 메타 문자로 인식되지 않는다. 이것을 이스케이프라고 한다.

특정 문자를 지정하는 메타 문자

임의의 문자 하나가 아니라 여러 문자 중 하나를 지정하고 싶다면 메타 문자 []를 사용한다.
t[ef]sttest혹은 tfst라는 문자열이 검색된다.
이 메타 문자는 괄호 안에 있는 문자 중 하나를 의미하는 것이다.

알파벳 a부터 k까지를 지정하고 싶다면 문자 범위를 표현하는 하이픈을 사용하여 a-k 라고 쓴다. [a-zA-z]는 알파벳 전체를 의미하겠다.

지정한 문자 이외의 문자를 찾을 수도 있다.
괄호 안에 첫 글자로 ^를 지정하고 mail[^13] 을 입력하면, mail 뒤에 13 이외의 문자를 의미하며 포함된 문자열은 검색에서 제외된다.

위치를 지정하는 메타 문자

다른 메타 문자와 조합하여 위치를 지정할 때 사용된다.

^는 행의 첫 부분을, $는 문장의 마지막을 의미한다.
^$를 함께 지정할 수도 있다.
^%는 시작이 곧 끝인 행을 의미하는데, 이는 빈 행을 의미한다.

다음과 같이 검색하면 빈 행을 제거한 결과를 얻을 수 있다.

반복을 지정하는 메타 문자

다른 정규 표현식의 뒤에서 사용되어 직전의 정규 표현식이 일정 횟수만큼 반복되는 것을 의미한다.

다음과 같은 파일이 있다.

*는 0회 이상의 반복을 의미하는데, 여기서 0회가 의미하는 것은 직전의 문자가 나타나지 않는 것도 포함한다는 뜻이다.
다음과 같이 Br도 해당된다. 하지만 Bear은 해당되지 않는다.

메타 문자 뒤에도 사용 가능한데, 다음은 ea가 0번 이상 반복되는 것을 검색한다.

임의의 문자를 나타내는 .과 함께 .* 같은 정규 표현식이 많이 사용되는데, 이는 임의의 문자가 0회 이상 반복되는 것을 의미하므로 결국 모든 문자열을 의미한다.
^ex.*txt$ex로 시작해 txt로 끝나는 행을 검색한다.

확장 정규 표현식이란

지금까지는 기본 정규 표현식이라 불리는 것으로 정규 표현식을 지원하는 모든 명령어에서 사용이 가능하다. 그리고 메타 문자가 늘어난 확장 정규 표현식도 있다. (이를 지원하지 않는 명령어도 있다)

grep-E 옵션을 지정하면 확장 정규 표현식으로 해석한다.

기본 정규 표현식에는 검색되지 않았지만 -E를 붙이니 확장 정규 표현식으로 검색된다.

리눅스의 grep-E 옵션을 붙이지 않고 메타 문자에 \를 붙여서 일부 확장 정규 표현식을 사용하는 것이 가능하다. 하지만 다른 명령어에서는 불가하니 명시적으로 -E를 붙이는 것이 좋다.

확장 정규 표현식에서 반복 횟수를 지정

+는 바로 전 문자가 1회 이상 반복되는 것을 의미한다. *와는 바로 전의 문자가 최소 1번 이상 나타나는 패턴이라는 것에서 차이가 있다.

?는 0회 혹은 1회를 의미한다. 다음과 같이 공백에 이어 사용하면 있거나 없는 경우 모두 검색한다.

반복 횟수를 지정하는 메타 문자

반복 횟수 지정은 {}를 사용한다. 이 사용법은 기본 정규 표현식과 확장 정규 표현식이 다르다.
확장 정규 표현식을 기준으로 소개한다.

[m,n]m회 이상, n회 이하를 의미한다.
Be{1,2}rBr 사이 e1회 이상 2회 이하 반복된다를 의미한다.

{m} 은 정확히 m 번 반복되는 패턴을 의미한다.

이는 전화번호나 우편번호와 같이 자릿수가 정해진 숫자 패턴을 지정할 때 유용하다.
전화번호는 [0-9]{3}-[0-9]{4}-[0-9]{4}와 같이 지정한다.

{m,}m회 이상 반복을 의미한다.

그 외의 메타 문자

확장 정규 표현식을 기준으로 소개한다.
() 는 정규 표현식을 그룹화할 때 사용한다. 예를 들어 Wine이란 네 글자가 2회 이상 반복해서 나타나는 경우를 검색하고 싶을 때 Wine{2,} 같이 지정하면 Wineeeee와 같은 패턴이 검색된다. 이는 메타 문자가 바로 전 문자 하나에 한해서 적용되기 때문이다.
이때 (Wine){2,} 라고 지정해주면 Wine이라는 네 글자가 반복되는 패턴을 검색할 수 있다.

| 는 복수의 정규 표현식을 OR 조건으로 연결할 때 사용한다.
abc|xyzabc혹은 xyz라는 문자열에 해당한다.

두 가지를 활용해보면 다음과 같이 검색이 가능하다.

기본 정규 표현식에서는 () 사용을 하려면 앞에 \를 붙여주어야 하며, |는 사용할 수 없다.

정규 표현식 사용하기

정규 표현식은 Vim이나 less 명령어의 / 검색 기능에서도 사용이 가능하다.

profile
코드를 두드리면 문이 열린다

0개의 댓글