grep : AND 연산??

grep OR

regex 에 OR 연산(|)은 있지만, AND 연산은 없다.
예를 들어서..

『하늘과 바람과 별과 시』는 교과서에 수록되어 널리 알려진 시를 비롯해, 문학적 비중과 가치를 고려해 추린 총 99편의 시와 4편의 산문을 수록한, 전 연령대 대상의 윤동주 시집이다. 『별과 바람과 하늘과 시』가 아니다.

위 문구에서 ‘하늘’ 또는 ‘바람’이 나오는지 알아내고 싶다면? (눈으로 읽어보면 알지 않냐??)
| 를 써주면 된다.

$ echo "『하늘과 바람과 별과 시』는 교과서에 수록되어 널리 알려진 시를 비롯해, 문학적 비중과 가치를 고려해 추린 총 99편의 시와 4편 의 산문을 수록한, 전 연령대 대상의 윤동주 시집이다. 『별과 바람과 하늘과 시』가 아니다." | grep '하늘\|바람'

『 하늘바람과 별과 시』는 교과서에 수록되어 널리 알려진 시를 비롯해, 문학적 비중과 가치를 고려해 추린 총 99편의 시와 4편의 산문을 수록한, 전 연령대 대상의 윤동주 시집이다. 『별과 바람하늘과 시』가 아니다.

이렇게 OR 연산은 간단한데.. AND 는 편법(?)을 써야 한다.
그리고, 원활한 결과를 위해서는 Perl Regex 가 적합한 듯 하다. BRE(Basic REgex), ERE(Extended REgex) 모두 제대로 작동하지 않았다.

grep AND

여기서 찾을 문구는 두 개다. ‘하늘’, ‘바람’. 헌데, 어떤게 먼저 나올 지는 알 수가 없다. 하늘이 먼저 나오고 나중에 바람이 나올 수도, 그 반대일 수도. 따라서 이 두가지를 모두 고려한 후, OR 연산을 해주면 되겠다.

grep '하늘.*바람\|바람.*하늘'

BRE 문법에선, OR 연산자를 이스케이프 해줘야 한다. 따라서 | 가 아니고 \| 다. 이렇다는 건, ERE/PCRE 에선 그냥 | 면 족하다는 얘기겠지?

그런데.. 위 결과가 좀..

하늘과 바람과 별과 시』는 교과서에 수록되어 널리 알려진 시를 비롯해, 문학적 비중과 가치를 고려해 추린 총 99편의 시와 4편의 산문을 수록한, 전 연령대 대상의 윤동주 시집이다. 『별과 바람과 하늘과 시』가 아니다.

이렇게 표시가 됐다. 내가 원했던 결과와는, 즉, ‘하늘과 바람’, 그리고 ‘바람과 하늘’ 과는 엄청난 차이가 있다. 이건 Greedy/Lazy 문제다.
그리하여, Lazy 로 문법을 바꿔보면.. 여기선 egrep 로. (BRE/ERE 나 결과는 같다.)

grep -E '하늘.*?바람|바람.*?하늘'

그래도 결과는 위와 같다.

따라서, PCRE 를 써야할 수 밖에 없다.

grep -P '하늘.*?바람|바람.*?하늘'

이 명령으로, ‘하늘과 바람’, ‘바람과 하늘’이 선택됐다. (결과 옮기기는 귀찮아서 생략.)

결론!

foo 와 bar 가 동시에 나오는지 grep 로 확인하려면, PCRE 를 사용하고, 다음과 같이 regex 를 작성한다.

grep -P 'foo.*?bar|bar.*?foo'
Author: 아무도안

안녕하세요. 글 남겨주셔서 고맙습니다.