sed는 스트림 편집기(stream editor)로, 텍스트 스트림을 편집하고 변환하는 데 사용되는 강력한 도구이다. sed는 주로 리눅스 및 유닉스 환경에서 활용되며, 특히 스크립트 및 대량 텍스트 처리에 유용하다. 이 글에서는 sed 사용법에 대해 알아본다.
기본 문법
sed OPTIONS 'COMMAND' FILE
OPTIONS: sed 명령어의 옵션을 지정COMMAND: sed에서 실행할 명령을 정의FILE: 편집하려는 대상 파일의 경로 지정
OPTIONS
sed 명령어의 옵션을 지정한다.
| option | description |
| -e | 조건식 스크립트를 직접 지정 |
| -f | 조건식 스크립트가 기재된 파일을 지정 |
| -n | 패턴이 일치하는 라인만 출력 |
| -r | 확장 정규표현을 사용한 스크립트를 사용 |
| -i | 수정한 내용으로 파일 덮어쓰기 |
COMMAND
sed에서 실행할 명령을 정의한다. h/H/g/G는 현재 처리 중인 라인이 담긴 패턴 스페이스와, 값을 잠시 보관해두는 홀드 스페이스 사이에서 내용을 주고받는 명령이다.
| command | description |
| a\ | 현재 행에 하나 이상의 새로운 행 추가 |
| c\ | 현재 행의 내용을 새로운 내용으로 교체 |
| d | 행 삭제 |
| i\ | 현재 행 위에 텍스트 삽입 |
| h | 패턴 스페이스의 내용을 홀드 스페이스로 복사(덮어쓰기) |
| H | 패턴 스페이스의 내용을 홀드 스페이스 끝에 추가 |
| g | 홀드 스페이스의 내용을 패턴 스페이스로 복사(덮어쓰기) |
| G | 홀드 스페이스의 내용을 패턴 스페이스 끝에 추가 |
| l | 패턴 스페이스를 제어문자까지 보이는 형태로 출력 |
| p | 패턴 스페이스 출력 (주로 -n과 함께 사용) |
| n | 현재 패턴 스페이스를 출력한 뒤 다음 입력 라인을 읽어옴 |
| q | 처리를 즉시 종료 |
| r | 지정한 파일의 내용을 읽어 출력에 추가 |
| ! | 뒤따르는 명령의 적용 대상을 반전 (주소에 매칭되지 않는 라인에 적용) |
| s | 문자열 치환 |
주요기능
문자열 치환 (s)
가장 많이 쓰는 기능은 s/패턴/치환문자열/플래그 형태의 치환이다.
# 각 행에서 처음 나오는 foo를 bar로 치환
sed 's/foo/bar/' file.txt
# 행 전체에서 모든 foo를 bar로 치환 (g 플래그)
sed 's/foo/bar/g' file.txt
# 대소문자 구분 없이 치환 (i 플래그)
sed 's/foo/bar/gi' file.txt
# 파일을 직접 수정 (백업 확장자 지정)
sed -i.bak 's/foo/bar/g' file.txt
행 삭제 (d)
# 3번째 행 삭제
sed '3d' file.txt
# 5~10번째 행 삭제
sed '5,10d' file.txt
# 특정 패턴이 포함된 행 삭제
sed '/DEBUG/d' file.txt
# 빈 줄 삭제
sed '/^$/d' file.txt
특정 라인만 출력 (-n, p)
-n 옵션으로 기본 출력을 끄고 p 명령으로 원하는 라인만 출력할 수 있다. grep과 비슷하게 쓰이지만 라인 범위 지정이 더 유연하다.
# 2~4번째 행만 출력
sed -n '2,4p' file.txt
# 패턴이 일치하는 행만 출력 (grep과 유사)
sed -n '/ERROR/p' file.txt
# 짝수 번째 행만 출력
sed -n '0~2p' file.txt
여러 명령 조합
-e를 여러 번 쓰거나 세미콜론(;)으로 구분하면 한 번의 sed 호출로 여러 명령을 순서대로 적용할 수 있다.
sed -e 's/foo/bar/g' -e '/DEBUG/d' file.txt
# 위와 동일한 결과
sed 's/foo/bar/g; /DEBUG/d' file.txt
홀드 스페이스로 라인 순서 뒤집기
홀드 스페이스는 라인 사이에 값을 넘겨야 하는 상황(파일 전체 뒤집기, 여러 줄 패턴 매칭 등)에 쓴다. tac과 동일한 동작을 sed만으로 구현하면 다음과 같다.
# 파일의 행 순서를 뒤집는다 (tac과 동일)
sed '1!G;h;$!d' file.txt
주의사항
- GNU sed와 BSD/macOS sed는
-i옵션 문법이 다르다. GNU sed는-i단독으로 바로 덮어쓰기가 가능하지만, macOS 기본 sed는-i ''처럼 백업 확장자(빈 문자열이라도)를 명시해야 한다. - 기본 정규표현식(BRE)에서는
+,?,|같은 확장 메타문자를 그대로 쓸 수 없다. 이런 문법이 필요하면-r(GNU) 또는-E(BSD) 옵션으로 확장 정규표현식(ERE)을 켜야 한다. -i로 파일을 직접 덮어쓰기 전에는 반드시-i.bak처럼 백업을 남기거나, 옵션 없이 먼저 결과를 눈으로 확인한 뒤 적용하는 편이 안전하다.
마무리
sed는 치환(s)과 삭제(d), 라인 범위 지정(-n/p)만 익혀도 셸 스크립트에서 텍스트를 다루는 대부분의 상황을 처리할 수 있다. 홀드 스페이스를 활용한 다중 라인 처리는 자주 쓰이진 않지만, 로그 파일을 역순으로 보거나 여러 줄에 걸친 패턴을 다뤄야 할 때 awk나 스크립팅 언어 없이도 한 줄로 해결할 수 있다는 점에서 알아두면 유용하다.