sed 명령어: 문자열 치환, 줄 삭제와 -i 옵션 사용법

공정위 광고 문구 Ver 3.1
공정위 광고 문구 Ver 3.2(모바일 전용)
테스트 환경RHEL 계열AlmaLinux 9.8root 계정2026-10-28 확인

sed 명령어는 파일 내용을 한 줄씩 읽어 바꾸기와 지우기, 넣기를 실행하는 리눅스 도구로, 편집기를 열지 않고 설정 파일의 값을 고칠 수 있습니다. AlmaLinux 9 서버에서 워드프레스 wp-config.php 사본에 sed를 실행한 결과, -i.bak으로 원본을 남긴 채 데이터베이스 이름을 바꿀 수 있었습니다.

글에 실은 오류 문구는 영어 locale에서 출력한 그대로입니다.

1️⃣ sed 명령어 기본 사용법과 s 치환

가장 많이 사용하는 s 명령은 [s/찾을 문자열/바꿀 문자열/] 형식으로 문자열을 치환합니다. 한 줄에서 처음 찾은 하나만 바꿉니다.

echo 'http://example.com http://example.com/blog' | sed 's/http:/https:/'
https://example.com http://example.com/blog

줄 안의 모든 문자열을 바꾸려면 끝에 g 플래그를 붙입니다.

echo 'http://example.com http://example.com/blog' | sed 's/http:/https:/g'
https://example.com https://example.com/blog

파일 이름을 뒤에 붙이면 그 파일을 읽어 바꾼 결과를 출력합니다. 워드프레스의 wp-config-sample.php를 wp-config.php로 복사한 사본에서 DB_USER 값을 바꾸고, grep으로 그 줄만 확인했습니다.

sed 's/username_here/wp_user/' wp-config.php | grep DB_USER
define( 'DB_USER', 'wp_user' );

출력에서 값이 바뀌었으니 파일도 바뀌었다고 여기기 쉬우나, sed는 옵션 없이 실행하면 결과를 화면에만 출력하고 원본 파일은 그대로 둡니다. 같은 줄을 파일에서 다시 찾아보니 처음 값이 그대로 남아 있었습니다.

grep DB_USER wp-config.php
define( 'DB_USER', 'username_here' );

원본 파일까지 바꾸려면 4️⃣의 -i 옵션을 사용합니다.

2️⃣ sed 줄 번호와 패턴으로 줄 고르기(-n, p)

s 명령은 주소 없이 실행하면 모든 줄에 적용되므로, 특정 줄만 다루려면 명령 앞에 줄 번호나 패턴을 주소로 적습니다. -n은 자동 출력을 끄고 p는 고른 줄을 출력합니다. 둘을 함께 쓰면 23행 하나만 나옵니다.

sed -n '23p' wp-config.php
define( 'DB_NAME', 'database_name_here' );

쉼표로 두 줄 번호를 이으면 그 범위가 나옵니다. 23행부터 32행까지는 데이터베이스 이름과 사용자, 비밀번호, 호스트 설정이 들어 있는 구간입니다.

sed -n '23,32p' wp-config.php
define( 'DB_NAME', 'database_name_here' );

/** Database username */
define( 'DB_USER', 'username_here' );

/** Database password */
define( 'DB_PASSWORD', 'password_here' );

/** Database hostname */
define( 'DB_HOST', 'localhost' );

줄 번호 대신 슬래시 사이에 패턴을 적으면 그 패턴이 들어 있는 줄을 모두 고릅니다.

sed -n '/DB_/p' wp-config.php
define( 'DB_NAME', 'database_name_here' );
define( 'DB_USER', 'username_here' );
define( 'DB_PASSWORD', 'password_here' );
define( 'DB_HOST', 'localhost' );
define( 'DB_CHARSET', 'utf8mb4' );
define( 'DB_COLLATE', '' );

[=] 명령은 고른 줄의 번호를 출력합니다. 주소 $는 마지막 줄을 의미하므로 [$=]로 파일 전체 줄 수를 확인할 수 있습니다.

sed -n '/DB_HOST/=' wp-config.php
32
sed -n '$=' wp-config.php
102

주소는 s 명령 앞에도 붙일 수 있습니다. 아래는 32행에서만 localhost를 바꾸고 p 플래그로 바뀐 줄만 출력한 결과입니다.

sed -n '32s/localhost/127.0.0.1/p' wp-config.php
define( 'DB_HOST', '127.0.0.1' );

-n 없이 p를 실행해 보니 고른 줄이 한 번 더 나왔습니다. sed는 줄을 하나씩 패턴 공간에 읽어 명령을 실행한 뒤 패턴 공간을 자동으로 출력하므로, p로 출력한 2행이 자동 출력으로 다시 나옵니다.

sed '2p' wp-config.php | head -n 4
<?php
/**
/**
 * The base configuration for WordPress

줄을 하나씩 읽어 처리하는 이 방식은 공장 컨베이어 벨트가 부품을 하나씩 작업대에 올려 가공한 뒤 다음 부품으로 넘기는 것과 같습니다.

명령에 따라 줄마다 무엇이 출력되는지는 아래 다이어그램에서 차례로 비교할 수 있습니다.

🧭 sed 패턴 공간과 자동 출력: 2행에 p, d
설명 다이어그램
⚙️ 명령
$ sed '2p'-n '2p''2d' wp-config.php
읽은 줄명령 실행과 출력
1행 → 패턴 공간<?php
➜
주소 2와 다름: 명령 없음자동 출력 1번-n이라 출력 없음
2행 → 패턴 공간/**
➜
주소 2와 같음: p 실행주소 2와 같음: d 실행p로 1번 + 자동 출력 1번p로 1번만 출력패턴 공간을 지우고 다음 줄로
3행 → 패턴 공간 * The base configuration for WordPress
➜
주소 2와 다름: 명령 없음자동 출력 1번-n이라 출력 없음
🖥️ 화면에 출력되는 것(1~3행)
<?php/**/** * The base configuration for WordPress
p는 패턴 공간을 한 번 더 출력하는 명령이라, -n 없이 실행하면 2행이 두 번 출력됩니다.
-n은 자동 출력을 끄므로, p로 고른 2행만 한 번 출력됩니다.
d는 패턴 공간을 지우고 다음 줄로 넘어가므로, 2행은 자동 출력되지 않습니다.

3️⃣ sed 명령어 줄 삭제와 삽입(d, i, a)

d는 고른 줄을 지우는 명령입니다. 아래 nginx 설정 견본에서 주석 줄을 빼고 보려면, #으로 시작하거나 # 앞에 공백만 있는 줄을 [^ *#] 패턴으로 고릅니다.

cat example.conf
# example.com
server {
    listen 80;
    server_name example.com www.example.com;

    # document root
    root /var/www/example.com;
    index index.php index.html;

    location / {
        try_files $uri $uri/ /index.php?$args;
    }
}
sed '/^ *#/d' example.conf
server {
    listen 80;
    server_name example.com www.example.com;

    root /var/www/example.com;
    index index.php index.html;

    location / {
        try_files $uri $uri/ /index.php?$args;
    }
}

세미콜론으로 명령을 이으면 빈 줄을 의미하는 [^$]까지 함께 지웁니다. 주석 줄을 지운 결과에 남아 있던 빈 줄 두 개가 사라지고 설정 줄만 남았습니다.

sed '/^ *#/d; /^$/d' example.conf
server {
    listen 80;
    server_name example.com www.example.com;
    root /var/www/example.com;
    index index.php index.html;
    location / {
        try_files $uri $uri/ /index.php?$args;
    }
}

i는 고른 줄 앞에, a는 고른 줄 뒤에 글자를 넣습니다. 1행 앞에 주석 한 줄을 넣은 결과는 아래와 같습니다.

sed '1i # managed by sed' example.conf | head -n 3
# managed by sed
# example.com
server {

a 뒤에 들여쓰기한 글자를 적으면 들여쓰기도 함께 들어간다고 여기기 쉬우나, GNU sed는 a 바로 뒤 공백을 건너뛰고 글자만 넣습니다.

sed '/index index.php/a    client_max_body_size 64M;' example.conf
# example.com
server {
    listen 80;
    server_name example.com www.example.com;

    # document root
    root /var/www/example.com;
    index index.php index.html;
client_max_body_size 64M;

    location / {
        try_files $uri $uri/ /index.php?$args;
    }
}

들여쓰기를 지키려면 a 뒤에 역슬래시를 붙입니다. 역슬래시 뒤 공백부터 글자로 들어갑니다.

sed '/index index.php/a\    client_max_body_size 64M;' example.conf
# example.com
server {
    listen 80;
    server_name example.com www.example.com;

    # document root
    root /var/www/example.com;
    index index.php index.html;
    client_max_body_size 64M;

    location / {
        try_files $uri $uri/ /index.php?$args;
    }
}

c는 고른 줄을 통째로 바꾸는 명령입니다. 아래는 listen 80 줄을 8080으로 바꾼 결과의 앞 네 줄입니다.

sed '/listen 80;/c\    listen 8080;' example.conf | head -n 4
# example.com
server {
    listen 8080;
    server_name example.com www.example.com;

4️⃣ sed -i 파일 직접 수정과 백업 파일 이름

-i는 결과를 화면 대신 원래 파일에 저장하는 옵션입니다. -i 바로 뒤에 붙인 글자는 백업 파일 이름 끝에 붙습니다. wp-config.php처럼 사이트가 읽는 파일은 -i.bak으로 원본을 남겨 두고 고칩니다.

cp wp-config-sample.php wp-config.php
sed -i.bak 's/database_name_here/wordpress_db/' wp-config.php

-i로 실행하면 화면에는 아무것도 출력되지 않으므로, ls -l로 파일을 확인합니다.

ls -l wp-config.php*
-rw-r--r-- 1 root root 3333 Oct 28 15:13 wp-config.php
-rw-r--r-- 1 root root 3339 Oct 28 15:13 wp-config.php.bak

고친 파일과 .bak 파일이 함께 생겼습니다. database_name_here가 wordpress_db로 줄어든 만큼 크기가 6바이트 작아졌습니다. diff로 두 파일을 비교하면 바뀐 줄만 확인할 수 있습니다.

diff wp-config.php.bak wp-config.php
23c23
< define( 'DB_NAME', 'database_name_here' );
---
> define( 'DB_NAME', 'wordpress_db' );

바뀐 줄은 23행의 DB_NAME 한 줄입니다.

바꿀 값이 여럿이면 -e로 스크립트를 이어 한 번에 실행합니다.

sed -i -e 's/username_here/wp_user/' -e 's/password_here/wp_pass/' wp-config.php
grep -n -e DB_USER -e DB_PASSWORD wp-config.php
26:define( 'DB_USER', 'wp_user' );
29:define( 'DB_PASSWORD', 'wp_pass' );

-i와 -e를 [-ie]처럼 붙여 쓰면 e까지 백업 이름으로 읽혀, 아래처럼 wp-config.phpe 파일이 생겼습니다.

sed -ie 's/127.0.0.1/localhost/' wp-config.php
ls wp-config.php*
wp-config.php
wp-config.php.bak
wp-config.phpe

-i는 고친 내용을 새 파일에 쓴 뒤 원래 이름으로 바꿔 넣으므로, 실행 전후 파일의 inode 번호가 달라집니다.

ls -i wp-config.php
207618887 wp-config.php
sed -i 's/localhost/127.0.0.1/' wp-config.php
ls -i wp-config.php
207618883 wp-config.php

실행 전 207618887이던 inode 번호가 207618883으로 바뀌었습니다.

파일이 없거나 파일 이름을 빠뜨리면 아래 오류로 끝나고 아무 파일도 바뀌지 않습니다.

sed -i 's/x/y/' no-such.php
sed: can't read no-such.php: No such file or directory
sed -i 's/x/y/'
sed: no input files

5️⃣ sed 명령어 정규식, 구분자 변경과 옵션

🔲 정규식과 구분자 변경

경로처럼 슬래시가 든 값을 바꾸면 s 명령의 구분자와 값의 슬래시가 섞이므로, 값의 슬래시마다 역슬래시를 붙여야 합니다.

sed -n 's/\/var\/www\/example.com/\/srv\/www\/example.com/p' example.conf
    root /srv/www/example.com;

s 바로 뒤 글자가 구분자가 되므로, 값에 없는 | 로 바꾸면 역슬래시 없이 같은 결과가 나옵니다.

sed -n 's|/var/www/example.com|/srv/www/example.com|p' example.conf
    root /srv/www/example.com;

패턴의 점(.)은 아무 글자 하나와 맞습니다. 아래는 example.com을 찾는 패턴이 exampleXcom까지 바꾼 결과입니다.

echo 'exampleXcom example.com' | sed 's/example.com/test.org/g'
test.org test.org

점을 글자 그대로 찾으려면 앞에 역슬래시를 붙입니다.

echo 'exampleXcom example.com' | sed 's/example\.com/test.org/g'
exampleXcom test.org

괄호로 묶은 부분은 바꿀 문자열에서 [\1]로 다시 불러옵니다. -E를 붙이면 괄호와 +를 역슬래시 없이 사용합니다. 아래는 listen 뒤 숫자를 그대로 두고 default_server를 덧붙인 결과입니다.

sed -nE 's/listen ([0-9]+);/listen \1 default_server;/p' example.conf
    listen 80 default_server;

-E 없이 같은 스크립트를 실행하면 괄호를 글자로 읽어, 불러올 묶음이 없다는 오류가 납니다. -E 없이 사용하려면 괄호와 +에 역슬래시를 붙입니다.

sed -n 's/listen ([0-9]+);/listen \1 default_server;/p' example.conf
sed: -e expression #1, char 46: invalid reference \1 on `s' command's RHS
sed -n 's/listen \([0-9]\+\);/listen \1 default_server;/p' example.conf
    listen 80 default_server;

바꿀 문자열의 [&]는 패턴에 맞은 글자 전체를 의미하므로, 맞은 부분 앞에 # 를 붙여 그 줄을 주석으로 만들 수 있습니다.

sed -n 's/server_name .*;/# &/p' example.conf
    # server_name example.com www.example.com;

🔲 sed 명령어 옵션

📌 주요 옵션: 이 글에서 실행한 결과

옵션하는 일이 글에서 본 결과
-n자동 출력을 끄고 p로 고른 줄만 출력sed -n '23p'로 23행 한 줄만 나옴, -n 없이 2p는 2행이 두 번
-i결과를 화면 대신 원래 파일에 저장(바로 뒤 글자는 백업 이름 끝에 붙음)-i.bak으로 wp-config.php.bak이 생김, 실행 뒤 inode 번호가 바뀜
-e스크립트 여러 개를 이어 한 번에 실행DB_USER와 DB_PASSWORD 두 값이 한 번에 바뀜, -ie로 붙이면 wp-config.phpe 백업이 생김
-E확장 정규식 사용(괄호와 +에 역슬래시 없이)listen 80 default_server; 출력, -E 없이 같은 스크립트는 [invalid reference] 오류
--follow-symlinks-i와 함께 링크가 가리키는 원본 파일을 고침없으면 링크 자리에 일반 파일이 생기고 원본 그대로, 붙이면 원본 값이 바뀜

📎 그 밖의 옵션: 공식 매뉴얼 기준

옵션하는 일
-f스크립트를 파일에서 읽어 실행
-r-E와 같은 확장 정규식(이식성은 -E)
-s여러 파일을 이어진 하나가 아니라 파일마다 따로 처리
-z줄을 줄바꿈 대신 널 문자로 나눔
-u입력을 조금씩 읽고 출력을 더 자주 내보냄
--posixGNU 확장 기능을 모두 끔
--debug실행 과정을 풀어서 출력

🔲 sed 명령어 시뮬레이터

아래 시뮬레이터의 작업 폴더에는 wp-config.php 사본과 example.conf가 있습니다. 지금까지의 명령을 직접 입력하고, -i로 바뀐 파일은 ls -l과 diff로 확인할 수 있습니다.

sed 명령어 시뮬레이터GNU sed
[root@server work]#
키보드 ↑↓ 로 앞에서 쓴 명령을 다시 불러옵니다.

🔢 FAQ & 추천 콘텐츠

워드프레스의 wp-config-sample.php는 줄 끝이 CRLF여서, 줄 끝 바로 앞에 보이지 않는 [\r]가 있습니다. [/false );$/]로는 아무 줄도 출력되지 않았고, [s/\r$//]로 [\r]를 지운 사본에서는 같은 패턴이 WP_DEBUG 줄을 찾았습니다.

-i는 링크 자리에 일반 파일을 새로 만들어 저장하므로, 링크가 가리키던 원본은 바뀌지 않았습니다. 원본 파일을 고치려면 [--follow-symlinks]를 함께 지정합니다. 이때는 링크가 그대로 남고 원본 값이 바뀌었습니다.

NEW=wp_user로 넣어 둔 변수도 작은따옴표 안에 쓰면 셸이 치환하지 않아 [$NEW]가 글자 그대로 들어갑니다. 스크립트를 큰따옴표로 감싸면 셸이 변수를 먼저 치환해, [$NEW] 자리에 wp_user가 들어갔습니다.

🧭 텍스트 명령어 추천 콘텐츠 글 9 · 참조 2
🗂️ 텍스트 보기 · 편집 명령어
📄 grep 명령어 📄 sort 명령어 📄 uniq 명령어 📄 tee 명령어 📄 sed 명령어
📄 cat 명령어 📄 less 명령어 📄 head · tail 명령어 📄 vi · vim 명령어

ℹ️ 제휴 안내
본 사이트의 콘텐츠에는 제휴 링크가 포함되어 있습니다. 방문자가 이 링크를 통해 상품 또는 서비스를 구매하면 본 사이트는 판매처로부터 수수료를 지급받습니다. 이 과정에서 구매자가 지불하는 금액(이벤트 할인 시 금액이 내려갑니다↓)은 오르지 않습니다. 게시된 가격·할인·재고 정보는 작성 시점 기준이며 실제와 다를 수 있으므로, 구매 전 판매처에서 최종 확인하시기 바랍니다. 상품 선정과 평가는 자체 기준에 따라 작성되며, 수수료 지급 여부가 소개 순서나 평가 내용에 영향을 주지 않습니다.

답글 남기기

이메일 주소는 공개되지 않습니다. 필수 필드는 *로 표시됩니다

인간임을 증명하세요: 5   +   4   =