"왜 내 정규식은 서버에서 안 돌까?" grep, sed, awk, Emacs 환경을 넘나들며 호환성 오류 없이 어디서나 백발백중 작동하는 범용 정규표현식(Regex) 핵심 문법과 작성 전략을 알아봅니다.
정규표현식(Regex)을 사용할 때 가장 짜증 나는 순간이 언제인가요? 바로 "내 컴퓨터에서는 잘 되던 정규식이 서버나 다른 툴로 옮기면 먹통이 될 때"입니다. Perl이나 Python, JavaScript 환경에서 강력하고 화려한 고급 정규식 문법에 익숙해진 개발자일수록, 리눅스 터미널이나 레거시 환경에서 뼈아픈 실패를 경험하곤 합니다. 협업하는 동료에게 코드를 보냈을 때 "이거 안 돌아가는데요?"라는 말을 듣지 않으려면, 어디서나 작동하는 안전한 '공통 분모' 정규식을 알아야 합니다.
이 글에서는 리눅스 환경에서 가장 많이 쓰이는 grep, sed, awk, 그리고 개발자들의 오랜 도구인 Emacs까지 아우르는 범용 정규식 전략을 빠르게 정리했습니다.
최저 공통분모 찾기, awk, grep, sed의 합작
GNU 버전의 sed, awk, grep을 사용하고 있다면, 가장 먼저 기억해야 할 것은 -E 옵션(확장 정규표현식, ERE)입니다. sed와 grep을 실행할 때 -E 옵션을 붙여주면 세 가지 도구의 정규식 문법이 거의 일치하게 됩니다.
단, 한 가지 치명적인 예외가 있습니다. 바로 단어 경계 표현입니다.
-
grep / sed: 단어 경계를
\b및\B로 표현합니다. -
awk: 단어 경계를
\<및\>로 표현해야 작동합니다.
이 사소한 차이 하나 때문에 쉘 스크립트 전체가 꼬일 수 있으니 주의하세요.
독특한 이스케이프 규칙을 가진 Emacs
Emacs는 정규식 계의 '이단아' 같은 존재입니다. 앞서 말한 도구들과 비슷한 기능을 지원하지만, 문법 표기법이 아주 독특합니다.
-
메타문자 이스케이프: Emacs에서는
+,?,(,),{,},|같은 기본 확장 메타문자를 사용할 때, 반드시 앞에 백슬래시(\)를 붙여야 메타문자로 작동합니다. (예:+가 아니라\+로 써야 1회 이상 반복이라는 뜻이 됩니다.) -
공백(Space) 클래스: 보통 공백을 뜻하는
\s와 공백이 아님을 뜻하는\S가 Emacs에서는 전혀 다른 의미로 쓰입니다. Emacs에서 공백 문자를 지정하려면\s-처럼 뒤에 하이픈을 붙여야 합니다.
어디서나 통하는 '안전한' 범용 정규식 치트키
그렇다면 툴과 환경을 불문하고 그냥 안심하고 막 써도 되는 문법은 무엇일까요? 엄격한 의미에서 호환성이 입증된 ‘안전지대 문법 리스트’를 제공합니다.
| 메타문자 | 기능 명칭 | 비고 |
|---|---|---|
. |
임의의 한 문자 | 모든 환경 공통 |
^, $ |
줄의 시작과 끝 | 모든 환경 공통 |
[...], [^...] |
문자 클래스 (포함/제외) | 가장 안전함 |
* |
0회 이상 반복 | 모든 환경 공통 |
\w, \W |
알파벳+숫자 (포함/제외) | 대부분 지원 |
\b, \B |
단어 경계 (포함/제외) | awk 제외 공통 |
?, + |
0~1회, 1회 이상 반복 | ERE 필수 또는 Emacs 이스케이프 필요 |
| 또는 | |
OR 조건 (선택) | 환경별 이스케이프 확인 필요 |
{n,m} |
반복 횟수 지정 | 범위 지정 가능 |
(...) |
캡처 그룹 | 그룹화 및 역참조용 |
실무자 주의:
\d와 역참조(Backreference)의 함정
숫자를 뜻하는
\d는 아주 기초적인 문법 같지만, 놀랍게도 많은 리눅스 기본 툴(Pure Regex Flavor)에서 지원하지 않습니다. 안전하게 쓰려면 **[0-9]**를 직접 쓰는 버릇을 들이는 것이 좋습니다.
\1~\9을 이용한 캡처 그룹 역참조의 경우,gawk같은 특정 툴에서는 치환(Replacement) 문자열 내에서만 작동하고 정규식 자체 내에서의 매칭은 지원하지 않는 경우가 있습니다.
"생존형 정규식"을 작성하는 방법
소프트웨어를 마음대로 설치할 수 없는 원격 서버나, 고객사의 제한된 인프라 환경에서 작업해야 하는 '컴퓨팅 생존주의' 상황이라면, 문법을 최소한으로 좁혀야 합니다. 가장 안전한 방법은 화려한 Perl 스타일 문법을 포기하고, literals, [...], ., *, ^, $ 만으로 조합하는 것입니다. 코드는 조금 길어질지 몰라도, 이 방식으로 작성된 정규식은 지구상에 존재하는 거의 모든 시스템에서 '수정 없이 바로(Out of the box)' 작동합니다. 동료에게 보낼 스크립트를 짜고 있다면, 오늘부터 한 단계 낮춘 '범용 정규식'을 써보는 건 어떨까요?
자주 묻는 질문 (FAQ)
Q1. 정규식에서 \d가 작동하지 않을 때는 어떻게 해야 하나요?
A1. 일부 리눅스 기본 grep이나 awk 버전에 따라 \d 메타문자를 인식하지 못하는 경우가 많습니다. 이럴 때는 가장 클래식하고 안전한 방식인 [0-9] 문자 클래스로 대체하여 작성하시면 어디서나 완벽하게 작동합니다.
Q2. grep이나 sed에서 +나 ? 연산자가 무시됩니다.
A2. 기본 표준 정규표현식(BRE) 상태이기 때문입니다. 명령어 뒤에 -E 옵션을 붙여 확장 정규표현식(ERE) 모드를 활성화하거나, 메타문자 앞에 백슬래시를 붙여 \+, \? 형태로 이스케이프 해보세요.