이걸 해결하느라 한시간은 헤맨 듯 하다. 그래도, 이제는 구글을 뒤지면 답을 얻을 수 있다. (엄밀하게 말해 ‘구글’을 뒤지는 일은 없지만..)
sed 에 대해 간단히 정리하면, 이런 문법을 사용해야 한다.
sed "s/regex/replacement/g" file
위 구문은, file 을 읽어서, Regular Expressions 를 통해 ‘regex’ 를 찾고, ‘replacement’ 로 바꾸라는 뜻이 된다.
여기서 / 를 Delimiter 라고 부르는데, 꼭 / 일 필요는 없다. 아무 문자나 사용해도 되지만, 같은 글자를 사용해야 한다.
즉, 다음과 같이 해도 된다.
sed "s_regex_replacement_g" file
밑줄이 아니라 어떤 문자를 사용해도 된다.
다만!!!!
‘regex’ 에 Delimiter 가 들어있는 경우, 오류가 발생한다.
다음을 보자.
$ sed 's/home/user/home/userY/g' <<< "home/user" sed: -e expression #1, char 13: `s' 에 관한 알수 없는 옵션
home/user(regex) 를 home/userY(replacement) 로 바꾸고 싶었다. 그런데, regex 자체에 / 가 들어있기 때문에, sed 는 명령을 이해하기 어려운 상태가 됐다.
따라서 위와 같은 경우는 Delimiter 를 다음과 같이 바꿔주면, 원하는 결과를 얻을 수 있다.
$ sed 's_home/user_home/userY_g' <<< "home/user" home/userY
여기까진 예전부터 알고 있던 내용인데…
아 젠장!
sed 에는, 매칭이 된 문자가 있는 행을 삭제해버리는 기능도 있다. 매칭된 문자열만 삭제하는게 아니고, 매칭이 True 가 되는 행 자체를 지워버린다.
이 때 ‘d’ 명령을 쓰며, 자세한 설명은 또 누군가의 도움을 받아야 한다. (man page 에선 전혀 도움을 받을 수 없다. “d Delete pattern space. Start next cycle.
” 이게 다다.)
형식은 다음과 같다.
sed '/pattern/d' file
바꾸기(Substitute) 와 비슷하지만, Delimiter 가 시작부터 나오는 게 다르다.
그런데, 상황이 위와 똑같았기 때문에, 즉, pattern 에 슬래시가 들어가기에, 저대로 적용하면 오류가 발생했다.
그리하여, 다른 문자로 바꿔봤는데..
$ sed "_pattern_d" "./file_a" sed: -e expression #1, char 1: unknown command: `_'
왜 안되는거야.. delete 에는 안되는 거야???
Man Page 에서도 확실한 내용을 찾지 못해서 구글을 ‘통해’ 여기 저기 돌아다니기 시작.. 그리고 한 한시간 여??
답을 찾아냈다. Comment 중, AlexR 님이 쓴 내용에 이런 표현이 있었다.
sed "\:$Line:d"
아!!!! ㅆ ㅏ ㅇ!
여기에서도 이스케이핑을 해줘야 하다니. 으아아아아아아!!!
아쉽게도 저 내용에 대한 문서는 찾지 못했다.
이 글을 쓰고 나서 한참 시간이 흐른 뒤(2021.1월 말), 제대로된 문서를 찾을 수 있었다.
man page 내용은 그저 수박 겉핥기일뿐, Gnu 설명서에 모든 내용이 들어 있었다.
그 부분만 옮겨보면 다음과 같다.
\%regexp%
(The
%
may be replaced by any other single character.)This also matches the regular expression regexp, but allows one to use a different delimiter than
/
. This is particularly useful if the regexp itself contains a lot of slashes, since it avoids the tedious escaping of every/
. If regexp itself includes any delimiter characters, each must be escaped by a backslash (\
).
그리고, 위 글의 질문자의 글에서는, 아예 Delimiter 를 쓰지 않고도 됐다고 하는데..
sed -i "$LINE"'d' "$FILE"
나는 저렇게해선 성공하지 못했다.
아마도, $LINE 의 첫 행에 / 가 들어가 있어서 그런 모양이다.
어쨌든, 그래도 이 정도에서 해결할 수 있어서 다행이라고 해야 하려나.