메뉴 닫기

리눅스 sed 명령어로 문자열 치환과 삭제 완벽 가이드

리눅스 sed 명령어로 문자열 치환과 삭제 완벽 가이드

💡 sed 치환 명령부터 실전 예제까지, 한 번에 배우는 문자열 변환 기술

서버 관리나 로그 분석, 대량의 텍스트 파일을 다루는 작업을 하다 보면 특정 문자열을 일괄 변경하거나 삭제해야 하는 상황이 자주 생깁니다.
이럴 때 강력한 힘을 발휘하는 도구가 바로 리눅스 sed 명령어입니다.
특히 sed 's/old/new/g'와 같은 치환 구문은 단일 파일뿐만 아니라 수백 개의 파일에서도 빠르고 효율적으로 문자열을 변환할 수 있습니다.
복잡한 정규식 패턴을 활용하면 단순한 단어 변경을 넘어 문장의 구조까지 변형이 가능하죠.
이번 글에서는 sed의 기본 개념부터 자주 쓰이는 옵션, 그리고 실무에서 유용하게 활용할 수 있는 실전 예제까지 차근차근 살펴보겠습니다.

sed는 단순한 치환 도구를 넘어 강력한 텍스트 스트림 편집기이자, 스크립트 기반의 자동화 작업에도 활용 가능한 도구입니다.
따라서 sed 사용법을 익히면 반복적인 문자열 처리 작업에 드는 시간을 획기적으로 줄일 수 있습니다.
이 글을 읽고 나면 sed의 기본 원리부터 고급 활용법까지 자신 있게 사용할 수 있게 될 것이며, 파일 내 특정 패턴을 정규식으로 찾아서 치환하거나 삭제하는 작업도 한층 수월해질 것입니다.



🔍 sed란 무엇인가?

sed(Stream Editor)는 리눅스와 유닉스 계열 운영체제에서 널리 사용되는 텍스트 스트림 편집기입니다.
이 명령어는 파일의 내용을 직접 수정하지 않고, 표준 입력으로 받은 텍스트 스트림을 처리하여 결과를 출력하는 방식으로 동작합니다.
즉, 한 줄씩 읽어와 지정된 명령에 맞춰 변환, 삭제, 추가 등의 작업을 수행하는 것이죠.
그 덕분에 sed는 대규모 텍스트 처리나 로그 분석, 데이터 전처리 과정에서 매우 유용하게 쓰입니다.

기본적으로 sed는 명령과 패턴을 지정하면 해당 규칙에 따라 문자열을 찾아 치환하거나 제거합니다.
대표적인 구문 형식은 sed 's/old/new/g'이며, 여기서 s는 substitute(치환), old는 찾을 문자열, new는 바꿀 문자열, 그리고 g는 global(전체 치환)을 의미합니다.
이 명령어를 사용하면 파일의 모든 ‘old’ 문자열이 ‘new’로 변경됩니다.

📜 sed의 주요 특징

  • 빠른 텍스트 처리 속도로 대규모 파일 편집에 적합
  • 🖋️정규식을 활용한 패턴 매칭 지원
  • 📂파일 전체 또는 특정 라인 범위에만 명령 적용 가능
  • 🔄치환, 삭제, 추가, 출력 제어 등 다양한 편집 기능 제공
CODE BLOCK
# 'sample.txt' 파일에서 'apple'을 'orange'로 치환
sed 's/apple/orange/g' sample.txt

💡 TIP: sed는 결과를 표준 출력으로 보여주기 때문에, 원본 파일을 수정하려면 -i 옵션을 함께 사용해야 합니다.

✏️ sed 기본 치환 명령 사용법

sed에서 가장 많이 쓰이는 기능이 바로 문자열 치환입니다.
기본적인 형식은 다음과 같습니다.

CODE BLOCK
sed 's/찾을문자열/바꿀문자열/옵션' 파일명

여기서 s는 substitute(치환)를 의미하며, 마지막의 옵션에는 g(전체 치환), 숫자(해당 번째만 치환) 등을 지정할 수 있습니다.

🔄 자주 쓰이는 치환 예제

명령어 설명
sed ‘s/foo/bar/’ file.txt 각 줄의 첫 번째 foo를 bar로 변경
sed ‘s/foo/bar/g’ file.txt 모든 foo를 bar로 변경
sed -i ‘s/foo/bar/g’ file.txt 원본 파일에 직접 적용

⚠️ 주의: -i 옵션은 파일을 직접 수정하므로, 원본 파일을 반드시 백업한 후 사용하는 것이 안전합니다.

이처럼 sed 치환 명령은 간단하면서도 강력하여, 단순 단어 변경부터 정규식 기반의 복잡한 패턴 치환까지 폭넓게 활용할 수 있습니다.
다음 단계에서는 정규식을 결합해 더 강력한 텍스트 변환을 구현하는 방법을 살펴보겠습니다.



⚙️ 정규식을 활용한 고급 치환

sed의 진가는 정규식을 조합할 때 드러납니다.
문자 클래스, 그룹화, 앵커, 경계 등을 활용하면 단순한 문자열 치환을 넘어 문장 구조나 패턴 기반의 변환을 정교하게 수행할 수 있습니다.
또한 경로처럼 슬래시가 많은 텍스트를 다룰 때는 구분자를 바꿔 이스케이프 부담을 줄일 수 있습니다.

🧩 캡처 그룹과 역참조

기본 정규식(BRE)에서 괄호와 플러스는 이스케이프해 사용합니다.
패턴을 괄호로 묶어 그룹을 만들고, 치환부에서 \1, \2처럼 역참조로 재배치할 수 있습니다.
GNU/BSD sed에서 확장 정규식(ERE)을 쓰려면 -E(또는 일부 환경에서 -r) 옵션을 사용하면 괄호와 플러스를 이스케이프 없이 쓸 수 있습니다.

CODE BLOCK
# "성,이름"을 "이름 성"으로 바꾸기 (BRE)
sed 's/^\([^,]*\),\s*\([^,]*\)$/\2 \1/' names.txt

# 동일 작업(ERE)
sed -E 's/^([^,]*),\s*([^,]*)$/\2 \1/' names.txt

# 매칭된 전체 텍스트를 재사용 (&)
sed 's/[0-9][0-9]*/(&)/g' data.txt

📍 앵커와 단어 경계

줄의 시작과 끝을 지정하는 앵커 ^, $를 활용하면 특정 위치에 있는 텍스트만 안전하게 치환할 수 있습니다.
단어 경계는 GNU sed에서 \<, \>로 표현할 수 있어 부분 일치를 방지하는 데 유용합니다.

CODE BLOCK
# 라인 시작의 "ERROR"만 "WARN"으로
sed 's/^ERROR/WARN/' app.log

# 단어 전체 "cat"만 "dog"로 (concatenate 등은 제외)
sed 's/\<cat\>/dog/g' words.txt

🧭 구분자 변경과 이스케이프 최소화

경로처럼 슬래시가 많은 텍스트를 다룰 때는 치환 구분자를 임의의 문자로 바꿀 수 있습니다.
보통 #, |, @ 등을 사용해 가독성과 유지보수성을 높입니다.

CODE BLOCK
# 경로 치환: /var/www → /srv/www
sed 's#/var/www#/srv/www#g' nginx.conf

# | 구분자 사용
sed 's|http://|https://|g' urls.txt

🎛️ 플래그와 옵션으로 정밀 제어

치환 명령의 마지막에 붙는 플래그로 동작을 세밀하게 제어할 수 있습니다.
g는 한 줄에서 모든 일치 항목을 치환하고, 숫자는 해당 번째 일치만 바꿉니다.
대소문자 구분을 무시하려면 GNU sed에서 I 플래그를 사용합니다.
또한 w 파일 플래그로 매칭 라인을 별도 파일로 기록할 수 있습니다.

플래그 의미 예시
g 한 줄의 모든 일치 치환 sed 's/foo/bar/g' file
2,3… 해당 번째만 치환 sed 's/:/-/2' time.txt
I 대소문자 무시 sed 's/error/WARN/I' log
w 파일 매칭 라인을 파일에 기록 sed -n 's/foo/bar/w changed.txt' file

💡 TIP: 치환부에서 리터럴 앰퍼샌드(&)가 필요하면 \&로 이스케이프하세요.
또한 파일을 직접 수정할 때는 -i 옵션을 사용하고, 안전을 위해 백업 확장자(예: -i.bak)를 함께 지정하면 좋습니다.

🗑️ sed로 문자열 삭제하기

sed는 치환뿐 아니라 삭제에도 특화되어 있습니다.
텍스트 일부를 지우거나, 특정 패턴이 포함된 라인을 통째로 제거하고, 범위 지정으로 여러 줄을 한 번에 없애는 등 정리 작업을 빠르게 수행할 수 있습니다.
기본적으로 d 명령은 라인을 삭제하고, s/패턴// 형태의 치환은 매칭되는 문자열만 비워 삭제합니다.
정규식과 주소(라인 번호, 패턴)를 함께 쓰면 로그나 CSV, 설정 파일을 손쉽게 정돈할 수 있습니다.

🧹 문자열 일부만 삭제하기: s/// 치환 활용

치환 명령에서 바꿀문자열을 비우면 매칭된 텍스트가 제거됩니다.
정규식을 결합하면 숫자, 괄호, 공백 등 원하는 유형만 골라 삭제할 수 있습니다.

CODE BLOCK
# 모든 대괄호와 그 내용 제거: [INFO], [DEBUG] 등
sed 's/\[[^]]*\]//g' app.log

# 콤마와 공백 제거(정규식으로 공백 뭉치 정리)
sed 's/[ ,]\+//g' data.txt

# 접두사 "prefix-"만 제거
sed 's/^prefix-//' names.txt

🗂️ 특정 라인 삭제하기: d 명령

주소를 지정해 라인을 통째로 지울 수 있습니다.
라인 번호, 패턴, 범위(시작,끝) 지정이 모두 가능하며, ! 를 붙이면 조건의 반대를 의미합니다.

CODE BLOCK
# 1번째 라인 삭제
sed '1d' file.txt

# 10~20번째 라인 삭제
sed '10,20d' file.txt

# "ERROR"를 포함한 라인만 삭제
sed '/ERROR/d' app.log

# "OK"를 포함하지 않는 라인만 삭제(즉, OK만 남김)
sed '/OK/!d' result.txt

🧭 범위 기반 삭제: 패턴~패턴 구간

두 패턴으로 범위를 지정하면 해당 구간의 모든 라인을 지울 수 있습니다.
설정 파일에서 섹션을 제거하거나, 로그에서 특정 블록을 날릴 때 유용합니다.

CODE BLOCK
# BEGIN과 END 사이 블록 삭제(여러 번 등장해도 각 블록 삭제)
sed '/BEGIN/,/END/d' report.txt

# 섹션 헤더부터 빈 줄 전까지 삭제
sed '/^\[deprecated\]/,/^$/d' config.ini

🧴 잡다한 공백·빈 줄 정리

중복 공백이나 불필요한 빈 줄을 제거하면 파일이 훨씬 읽기 쉬워집니다.
아래 예제는 공백 뭉치와 연속 빈 줄을 압축해 간결하게 만들어 줍니다.

CODE BLOCK
# 연속되는 빈 줄을 한 줄로 축소
sed '/^$/N;/^\n$/D' notes.txt

# 라인 끝 공백 제거
sed 's/[ \t]\+$//' code.py

⚠️ 주의: 원본 파일을 직접 수정하려면 -i 옵션을 사용합니다.
macOS 기본 sed에서는 -i ''처럼 백업 확장자를 명시하는 형태가 자주 쓰입니다.
중요한 파일에는 -i.bak로 백업을 남긴 뒤 적용하는 것을 권장합니다.

  • 🧪먼저 표준 출력으로 테스트하고 결과가 기대와 같은지 확인합니다.
  • 💾실제 적용 시 -i.bak처럼 백업 확장자를 지정합니다.
  • 🎯패턴 삭제는 s/old//g, 라인 삭제는 /패턴/d처럼 용도에 맞는 구문을 사용합니다.



💡 sed 실전 활용 예제

현업에서 sed는 대량 파일의 문자열을 일괄 변경하거나, 정규식 조건에 맞춰 특정 조각을 삭제하는 데 자주 쓰입니다.
핵심 기본형은 sed 's/old/new/g' 파일명이며, 이는 파일 내 문자열을 정규식 기반으로 찾아 치환하는 표준 구문입니다.
여기에 옵션과 주소(라인 범위), 구분자 변경을 조합하면 로그 정리, 설정 마이그레이션, URL 일괄 수정 같은 반복 업무를 강력하게 자동화할 수 있습니다.
아래 예제들은 바로 복사해 써볼 수 있도록 상황별로 정리했습니다.

🧰 프로젝트 전역 치환: 확장자별, 디렉터리별 일괄 적용

CODE BLOCK
# 현재 디렉터리의 .conf 파일에서 http:// → https:// 일괄 변경(구분자 변경)
find . -type f -name "*.conf" -exec sed -i.bak 's|http://|https://|g' {} +

# src 디렉터리의 .js, .ts에서 foo → bar(대소문자 무시 I 플래그)
find src -type f \( -name "*.js" -o -name "*.ts" \) -exec sed -i.bak 's/foo/bar/gI' {} +

# 특정 서브디렉터리는 제외하고 치환
find . -type f -name "*.md" -not -path "./vendor/*" -exec sed -i.bak 's/\<TODO\>/DONE/g' {} +

💡 TIP: 실제 파일을 바꾸기 전, -np 플래그를 조합해 변경될 라인만 미리보기할 수 있습니다.
예: sed -n 's/old/new/gp' file처럼 쓰면 치환이 발생하는 라인만 출력됩니다.

🌐 URL·경로 마이그레이션: 구분자와 캡처 그룹

CODE BLOCK
# 베이스 도메인 변경: https://old.example.com → https://new.example.com
sed -i.bak 's|https://old\.example\.com|https://new.example.com|g' sitemap.xml

# 이미지 경로 재배치: /assets/img/2024/파일명 → /static/img/파일명
sed -E -i.bak 's#/assets/img/2024/([^"]+)#/static/img/\1#g' index.html

# 캡처 그룹으로 쿼리 파라미터 정리: ?id=123 → ?id=000123(6자리 패딩)
sed -E 's/(\?id=)([0-9]{1,6})/\1$(printf "%06d" \2)/' urls.txt

⚠️ 주의: 셸 확장과 혼동될 수 있는 백슬래시, 앰퍼샌드(&), 달러($)는 적절히 이스케이프하세요.
필요 시 작은따옴표와 큰따옴표를 바꾸거나 이중 이스케이프를 검토하면 안전합니다.

🧾 로그 정리: 레벨 접두사 제거와 블록 삭제

CODE BLOCK
# [INFO], [DEBUG] 같은 레벨 접두사 삭제
sed 's/\[[A-Z]\+\] //g' app.log

# 날짜가 2025-08-로 시작하는 라인만 남기기(그 외 삭제)
/bin/sed -n '/^2025-08-/p' app.log > only_aug.log

# BEGIN ~ END 사이의 디버그 블록 전체 삭제
sed '/^BEGIN DEBUG/,/^END DEBUG/d' app.log

📝 CSV·코드 스타일링: 공백·주석·열 정리

CODE BLOCK
# 라인 끝 공백 제거(탭 포함)
sed -i.bak 's/[ \t]\+$//' *.py

# 연속 빈 줄을 한 줄로 축소
sed '/^$/N;/^\n$/D' notes.md

# CSV에서 3번째 컬럼의 따옴표 제거("값" → 값)
sed -E 's/^(([^,]*,){2})"([^"]*)"/\1\3/' data.csv

환경 권장 in-place 문법 메모
GNU sed (리눅스 일반) sed -i.bak 's/old/new/g' file 백업 확장자 생략 가능하지만, 백업 파일 권장
BSD/macOS sed sed -i '' 's/old/new/g' file 또는 sed -i .bak 's/old/new/g' file 공백 백업 확장자('') 문법 자주 사용

💬 치환 결과를 따로 저장하려면 w 플래그를 활용하세요.
예: sed -n 's/old/new/gw changed.txt' file는 변경이 발생한 라인만 changed.txt에 기록합니다.

  • 🔎미리보기로 안전 확인: sed -n 's/old/new/gp' 파일명
  • 🛡️백업을 항상 남긴다: -i.bak 또는 -i ''
  • 🧭슬래시가 많은 값은 구분자 변경으로 가독성 확보: s#old#new#g

자주 묻는 질문 (FAQ)

sed ‘s/old/new/g’에서 g를 빼면 무엇이 달라지나요?
g를 빼면 각 라인의 첫 번째 일치만 치환되고 나머지는 그대로 남습니다.
g를 넣으면 한 라인에서 발견되는 모든 일치가 치환됩니다.
특정 번째만 바꾸려면 2,3처럼 숫자를 사용할 수 있습니다.
원본 파일을 직접 수정하려면 어떻게 하나요?
리눅스의 GNU sed에서는 -i 또는 -i.bak 옵션을 사용해 인플레이스 편집을 합니다.
macOS의 BSD sed에서는 -i ” 또는 -i .bak처럼 백업 확장자를 명시하는 문법을 자주 씁니다.
중요한 파일은 -i.bak로 백업을 남긴 뒤 적용하는 것을 권장합니다.
슬래시가 많은 경로를 치환할 때 이스케이프가 불편합니다. 해결 방법이 있나요?
치환 구분자를 / 대신 #, |, @ 등으로 바꿀 수 있습니다.
예를 들어 s#/var/www#/srv/www#g처럼 쓰면 슬래시를 일일이 이스케이프하지 않아도 됩니다.
구분자는 s 다음의 첫 문자로 인식됩니다.
대소문자 구분 없이 치환하려면 어떻게 하나요?
GNU sed에서는 치환 플래그에 I를 추가하면 대소문자를 무시합니다.
예: sed ‘s/error/WARN/I’ log.txt 같이 사용할 수 있습니다.
환경마다 지원 여부가 다를 수 있으므로 man sed로 확인하는 습관이 좋습니다.
정규식 캡처 그룹과 역참조는 어떻게 쓰나요?
기본 정규식(BRE)에서는 \(…\)로 그룹을 만들고 치환부에서 \1, \2처럼 참조합니다.
예: sed ‘s/^\([^,]*\),\s*\([^,]*\)$/\2 \1/’ names.txt 형태로 사용할 수 있습니다.
확장 정규식(ERE)을 쓰려면 -E 옵션을 주고 괄호를 그대로 사용합니다.
특정 단어만 정확히 치환하고 부분 일치는 피하려면요?
단어 경계를 사용합니다.
GNU sed에서는 \<와 \>를 이용해 \처럼 감싸면 concatenate의 cat은 제외하고 단어 cat만 치환합니다.
또는 공백, 구두점 등을 고려한 패턴으로 경계를 수동 구성할 수도 있습니다.
여러 파일에서 한꺼번에 문자열을 바꾸려면 어떻게 하나요?
find와 -exec 조합이 일반적입니다.
예: find . -type f -name “*.conf” -exec sed -i.bak ‘s|http://|https://|g’ {} + 형태로 일괄 적용할 수 있습니다.
변경 전에는 sed -n ‘s/old/new/gp’ 파일명으로 미리보기 출력을 확인하는 것을 추천합니다.
라인 전체를 삭제하거나 범위로 삭제할 수 있나요?
가능합니다.
/패턴/d는 해당 패턴을 포함한 라인을 삭제하고, 10,20d는 10~20번째 라인을 지웁니다.
/BEGIN/,/END/d처럼 두 패턴 사이의 구간을 통째로 삭제하는 것도 자주 사용하는 방법입니다.

🧾 한눈에 정리 sed 치환과 삭제 핵심 가이드

이 글에서는 리눅스에서 가장 널리 쓰이는 스트림 편집기 sed의 핵심 개념과 실전 활용법을 단계적으로 정리했습니다.
특히 sed 's/old/new/g' 구문을 중심으로, 파일 내 문자열을 정규식 기반으로 찾아 일괄 치환하거나 비워서 삭제하는 방법을 예제와 함께 설명했습니다.
기본 치환 원리, g·숫자 플래그의 차이, 단어 경계와 앵커, 캡처 그룹과 역참조, 구분자 변경 등 실무에 바로 적용 가능한 팁을 담았습니다.
라인 또는 범위 삭제(/패턴/d, 10,20d, /BEGIN/,/END/d)와 공백·빈 줄 정리처럼 유지보수에 유용한 기법도 다뤘습니다.
GNU sed의 -i 인플레이스 편집과 BSD/macOS sed의 백업 확장자 문법 차이, 안전한 테스트를 위한 -n·p 조합, w 플래그로 변경 라인 기록하기까지 확인했다면 대규모 텍스트 변환도 자신 있게 처리할 수 있습니다.


🏷️ 관련 태그 : sed, 리눅스명령어, 정규식, 문자열치환, 문자열삭제, 스트림에디터, 셸스크립트, 로그정리, 인플레이스편집, GNUsed