개요
sed(Stream Editor)는 텍스트 데이터를 스트림 단위로 처리하는 강력한 리눅스 도구입니다. 비대화형 방식으로 작동하며, 원본 파일을 직접 수정하지 않고도 텍스트 변환 작업을 수행할 수 있습니다. 기본적으로 처리 결과는 표준 출력에 표시되며, 변경 사항을 파일에 저장하려면 리다이렉션(>)을 사용해야 합니다.
작동 원리는 간단합니다. 입력된 각 라인은 일시적인 작업 공간인 패턴 공간(pattern space)에 로드됩니다. 이 공간에서 지정된 명령어들이 실행되고, 처리 완료 후 결과가 출력됩니다. 이후 해당 라인은 버퍼에서 제거되고 다음 라인이 읽혀지는 방식으로 순차적으로 진행됩니다. 이 구조 덕분에 sed는 대용량 파일 처리에도 효율적입니다.
라인 주소 지정
특정 라인 또는 범위에만 명령을 적용하기 위해 주소(address)를 사용할 수 있습니다. 주소는 숫자(행 번호), 정규 표현식, 또는 두 가지의 조합으로 구성됩니다. 주소를 생략하면 모든 라인에 명령이 적용됩니다.
3p: 3번째 라인만 출력$p: 마지막 라인 출력5,10d: 5번째부터 10번째 라인까지 삭제/start/,/end/d: "start"를 포함한 첫 번째 라인부터 "end"를 포함한 첫 번째 라인까지 삭제1,/STOP/q: 첫 번째 라인부터 "STOP"이 나오는 지점까지 처리 후 종료
주요 명령어
| 명령 | 기능 설명 |
|---|---|
| d | 현재 라인 삭제 |
| p | 현재 라인 출력 (보통 -n 옵션과 함께 사용) |
| s/old/new/g | 문자열 치환 (g: 전체 치환) |
| a\ | 현재 라인 뒤에 새 라인 추가 |
| i\ | 현재 라인 앞에 새 라인 삽입 |
| c\ | 현재 라인을 새로운 텍스트로 교체 |
| r filename | 외부 파일 내용을 현재 위치에 읽어들임 |
| w filename | 선택된 라인을 지정된 파일에 쓰기 |
| y/abc/xyz/ | 문자를 일대일로 변환 (예: a→x, b→y, c→z) |
| n | 다음 라인을 읽고 후속 명령 처리 |
| q | 즉시 처리 중단 |
| h/H | 패턴 공간 내용을 보관 영역(hold space)으로 복사 또는 누적 |
| g/G | 보관 영역 내용을 패턴 공간으로 가져와 덮어쓰거나 추가 |
| x | 패턴 공간과 보관 영역의 내용을 교환 |
옵션
- -n: 기본 출력 억제. 주로 p 명령과 함께 사용
- -e: 여러 개의 명령을 연속해서 지정
- -f script.sed: 외부 스크립트 파일에서 명령 읽기
- -i: 원본 파일 직접 수정 (주의 필요)
정규 표현식 지원
sed는 정규 표현식을 기반으로 검색 및 치환을 수행합니다. 패턴은 일반적으로 슬래시(/)로 감쌉니다. 필요 시 다른 구분자(예: #, @)를 사용할 수 있습니다.
# 슬래시 대신 # 사용
sed 's#http://example.com#/local#g'
# 단어 경계 매칭
sed '/\<error\>/p' logfile
# 문자 클래스 및 반복
sed 's/[0-9]\{4\}/****/g' # 4자리 숫자를 ****로 치환
실전 예제
조건부 출력
syntaxhighlighter-pre
# 'failed' 포함 라인만 출력
sed -n '/failed/p' system.log
# 10~20라인 중 'warning' 포함 라인 출력
sed -n '10,20{/warning/p}' alert.log
텍스트 삽입 및 추가
syntaxhighlighter-pre # 특정 패턴 뒤에 블록 추가 sed '/database_config/a\ timeout: 30s\ retries: 3' config.yml # 파일 시작 부분에 헤더 삽입 sed '1i\=== Auto-generated file ===' report.txt
문자열 치환
syntaxhighlighter-pre # 전역 치환 sed 's/old-domain.com/new-domain.org/g' site.conf # 그룹 캡처 및 재배치 sed 's/\(first\)\(second\)/\2:\1/' data.txt
파일 분할
syntaxhighlighter-pre # 에러 메시지만 별도 파일로 저장 sed -n '/ERROR/w errors_only.log' application.log
고급 제어: 보관 공간 활용
syntaxhighlighter-pre
# 마지막 라인에 이전에 매칭된 모든 라인 붙이기
sed '/backup/h; $G' status.log
# 여러 라인 누적 후 최종 출력
sed '/start/H; /end/{x;s/\n//g;p;}' segment.log
스크립트 파일 사용
복잡한 작업은 외부 스크립트로 관리하는 것이 좋습니다.
변환 스크립트(filter.sed):/^#/d # 주석 줄 제거 /^\s*$/d # 빈 줄 삭제 s/\s\+/:/g # 공백 여러 개를 콜론 하나로 a\--- END ---실행:
syntaxhighlighter-pre sed -f filter.sed input.txt
종료 상태
sed는 문법 오류가 없으면 항상 종료 코드 0을 반환합니다. 이는 grep과 달리 매칭 여부와 무관하게 성공으로 간주한다는 의미입니다. 따라서 스크립트에서 존재 여부를 판단할 때는 추가적인 방법이 필요합니다.