조희대의 개인 사이트
개인적이지만 유용한

sed에서 닫는 대괄호를 글자 클래스에 포함하기

sed 정규식의 글자 클래스를 구성할 때 붙임표(-, hyphen)를 맨 처음 또는 마지막에 포함시키면 범위가 아닌 붙임표 자체가 된다는 건 오래전부터 알고 잘 써 왔다. 그런데 Perl에서 쓰던 /[\[\]]/를 sed에서 쓰려니까 안 됐다. 검색을 해 보니 대괄호([, ], square brackets)도 붙임표와 마찬가지로 각각 맨 마지막과 처음에 포함시켜야 한다는 걸 배웠다.

$ echo "remove [ME]" | sed 's/[M\[\]E]//g'
remove [

\]는 예상대로 적용된다. 제일 넓은 [] 사이에 있는 M, E, ]를 제거했다. 그런데 \[가 제대로 안 된다.

echo "remove [ME]" | sed 's/[M\[]E]//g'
remove [

이건 원래 생각했던 것과는 다르게 작동하지만 같은 결과를 출력한다. 앞[] 사이에 있는 M을 제거하고 \[는 작동하지 않았다. 그런 다음 그 뒤의 E][] 바깥에서 제거되었다.

[를 제거하기 위해서는 문자 클래스의 맨 마지막에 위치시키면 된다.

$ echo "remove [ME]" | sed 's/[M\]E\[]//g'
remove [ME]

이렇게 하면 안 되고 다음과 같이 해도 안 된다.

echo "remove [ME]" | sed 's/[M\]E[]//g'
sed: -e expression #1, char 12: unterminated `s' command

이렇게 해야 한다.

echo "remove [ME]" | sed 's/[]ME[]//g'
remove

즉, 빈 문자 클래스처럼 보이게 정규식을 구성하면 대괄호를 포함시킬 수 있다. Perl에서도 같은 방법을 사용할 수 있고 \[\]같이 써도 된다.

우리는 여기서 의문이 생긴다. -, [, ]를 모두 포함시키고 싶으면 어떻게 하나? 앞서도 살펴 봤듯이 \]는 작동한다. 따라서 다음과 같이 쓰면 된다.

$ echo "remove [ME]-" | sed 's/[]ME\[-]//g'
remove

참고문헌

이 칸을 비워 두세요.