본문 바로가기
Q&A2026년 8월 12일1분 읽기

grep -P 로 lookahead 정규식을 쓰려는데 invalid option 이거나 아무것도 안 잡힙니다

r
regex_junho
조회 432댓글 1

로그에서 'ERROR' 뒤에 'timeout' 이 나오는 줄만 뽑으려고 lookahead를 썼는데, 어떤 서버에선 grep: invalid option -- P 라고 뜨고, 또 다른 데선 -P는 먹는데 패턴이 아무것도 안 잡힙니다.

$ grep -P '(?=.*ERROR)(?=.*timeout)' app.log
grep: invalid option -- P
# 다른 서버(리눅스)에서는
$ grep -P '(?=.*ERROR)(?=.*timeout)' app.log
(아무 출력 없음)

기본 정규식(BRE)에선 lookahead가 안 된다고 해서 -P(PCRE)를 붙였는데도 이 모양입니다. 맥 로컬이랑 리눅스 서버에서 동작이 제각각이라 뭐가 맞는 건지 헷갈립니다. 그냥 두 단어가 같은 줄에 있는 걸 찾고 싶은 건데요.

댓글 1

김김영삼2개월 전
두 가지가 겹쳤습니다. 하나는 grep 종류 차이, 하나는 lookahead 정규식 자체 오용입니다.

먼저 invalid option -- P 는 그 서버 grep이 GNU grep이 아니라 BSD grep(맥 기본)이라서 -P 옵션 자체가 없어서 나는 거예요. 맥 기본 grep은 PCRE(-P)를 지원 안 합니다. 리눅스 GNU grep은 -P가 되지만 빌드에 따라 PCRE가 빠져있으면 역시 안 될 수 있고요.

두 번째로, 리눅스에서 -P가 먹는데도 아무것도 안 잡힌 건 lookahead를 잘못 쓰셔서입니다. (?=.*ERROR)(?=.*timeout) 은 그 위치에서 앞을 내다보기만 하는 폭 0짜리(zero-width) 패턴이라 실제로 소비하는 문자가 없습니다. lookahead만 나열하면 매칭 길이가 0이라 줄을 제대로 못 집는 경우가 생겨요.

사실 '두 단어가 한 줄에 같이 있는 줄' 찾는 거면 lookahead까지 갈 필요가 없습니다. 그냥 이렇게 하세요.

grep ERROR app.log | grep timeout

파이프로 두 번 거르면 순서 상관없이 둘 다 든 줄만 나옵니다. 제일 이식성 좋고 확실해요. 한 방에 하고 싶으면 awk '/ERROR/ && /timeout/' app.log 도 깔끔하고요.

정 lookahead가 꼭 필요한 상황이면 grep -P 대신 이식성 있게 perl -ne 'print if /(?=.*ERROR)(?=.*timeout)/' 이나 ripgrep(rg)을 쓰는 걸 권합니다. 다만 맥/리눅스 섞인 환경이면 -P 의존은 언제든 또 깨지니, 저라면 그냥 파이프 두 번으로 갑니다.
Ctrl+Enter로 등록