Comando sed: sustitución de cadenas, eliminación de líneas y uso de la opción -i

Entorno de pruebaFamilia RHELAlmaLinux 9.8Cuenta rootVerificado el 2026-10-28

El comando sed es una herramienta de Linux que lee un archivo línea por línea y ejecuta sustituciones, eliminaciones e inserciones, de modo que puedes cambiar valores de un archivo de configuración sin abrir un editor. Al ejecutar sed en una copia de wp-config.php de WordPress en un servidor AlmaLinux 9, pudimos cambiar el nombre de la base de datos conservando el original con -i.bak.

Los mensajes de error de este artículo se muestran tal como salen con una locale en inglés.

1️⃣ Uso básico del comando sed y sustitución con s

El comando s, el más usado, sustituye cadenas con el formato [s/cadena a buscar/cadena nueva/]. Solo cambia la primera coincidencia de cada línea.

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

Para cambiar todas las cadenas de la línea, añade la bandera g al final.

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

Si añades un nombre de archivo al final, sed lee ese archivo y muestra el resultado cambiado. En una copia de wp-config-sample.php de WordPress hecha como wp-config.php, cambiamos el valor de DB_USER y comprobamos solo esa línea con grep.

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

Como el valor cambió en la salida, es fácil pensar que el archivo también cambió, pero sin opciones sed solo muestra el resultado en pantalla y deja el archivo original como está. Al volver a buscar la misma línea en el archivo, seguía el valor inicial.

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

Para cambiar también el archivo original, usa la opción -i de 4️⃣.

2️⃣ Seleccionar líneas en sed por número y patrón (-n, p)

Sin dirección, el comando s se aplica a todas las líneas, así que para trabajar solo con algunas escribe delante del comando un número de línea o un patrón como dirección. -n desactiva la impresión automática y p imprime las líneas seleccionadas. Juntos muestran solo la línea 23.

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

Si unes dos números de línea con una coma, aparece ese rango. Las líneas 23 a 32 son la sección con los ajustes del nombre de la base de datos, usuario, contraseña y host.

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' );

Si en lugar de un número de línea escribes un patrón entre barras, se seleccionan todas las líneas que contienen ese patrón.

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', '' );

El comando [=] imprime el número de la línea seleccionada. La dirección $ significa la última línea, así que con [$=] puedes ver el total de líneas del archivo.

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

La dirección también puede ir delante del comando s. Abajo está el resultado de cambiar localhost solo en la línea 32 e imprimir solo la línea cambiada con la bandera p.

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

Al ejecutar p sin -n, la línea seleccionada salió una vez más. sed lee las líneas una a una en el espacio de patrones, ejecuta los comandos y después imprime automáticamente el espacio de patrones, de modo que la línea 2 impresa por p vuelve a salir con la impresión automática.

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

Este método de leer y procesar línea por línea es como una cinta transportadora de fábrica que pone las piezas una a una en la mesa de trabajo, las procesa y pasa a la siguiente.

En el diagrama de abajo puedes comparar paso a paso qué se imprime en cada línea según el comando.

🧭 Espacio de patrones de sed e impresión automática: p y d en la línea 2
Diagrama explicativo
⚙️ Comando
$ sed '2p'-n '2p''2d' wp-config.php
Línea leídaEjecución del comando y salida
Línea 1 → espacio de patrones<?php
➜
Distinta de la dirección 2: sin comandoImpresión automática 1 vezSin salida por -n
Línea 2 → espacio de patrones/**
➜
Coincide con la dirección 2: se ejecuta pCoincide con la dirección 2: se ejecuta d1 vez por p + 1 vez automáticaSolo 1 vez por pBorra el espacio de patrones y pasa a la línea siguiente
Línea 3 → espacio de patrones * The base configuration for WordPress
➜
Distinta de la dirección 2: sin comandoImpresión automática 1 vezSin salida por -n
🖥️ Lo que sale en pantalla (líneas 1~3)
<?php/**/** * The base configuration for WordPress
p imprime el espacio de patrones una vez más, así que sin -n la línea 2 sale dos veces.
-n desactiva la impresión automática, así que solo sale una vez la línea 2 seleccionada con p.
d borra el espacio de patrones y pasa a la línea siguiente, así que la línea 2 no se imprime automáticamente.

3️⃣ Eliminar e insertar líneas con el comando sed (d, i, a)

d elimina las líneas seleccionadas. Para ver la configuración de ejemplo de nginx de abajo sin las líneas de comentario, selecciona con el patrón [^ *#] las líneas que empiezan por # o que solo tienen espacios delante de #.

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;
    }
}

Si unes comandos con punto y coma, también se elimina [^$], que significa línea vacía. Desaparecieron las dos líneas vacías que quedaban tras borrar los comentarios y solo quedaron las líneas de configuración.

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 inserta texto antes de la línea seleccionada y a lo inserta después. El resultado de insertar una línea de comentario antes de la línea 1 es el siguiente.

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

Es fácil pensar que si escribes texto sangrado después de a, la sangría también se incluye, pero GNU sed omite los espacios justo después de a e inserta solo el texto.

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;
    }
}

Para conservar la sangría, pon una barra invertida después de a. Lo que sigue a la barra invertida, espacios incluidos, entra como texto.

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 reemplaza por completo la línea seleccionada. Abajo están las cuatro primeras líneas del resultado de cambiar la línea listen 80 a 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️⃣ Edición directa de archivos con sed -i y nombre de la copia de seguridad

-i guarda el resultado en el archivo original en lugar de mostrarlo en pantalla. El texto escrito justo después de -i se añade al final del nombre de la copia de seguridad. wp-config.php y otros archivos que lee el sitio conviene editarlos con -i.bak para conservar el original.

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

Al ejecutar con -i no sale nada en pantalla, así que comprueba los archivos con 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

Quedaron juntos el archivo editado y el archivo .bak. El tamaño bajó 6 bytes porque database_name_here pasó a ser el más corto wordpress_db. Si comparas los dos archivos con diff, solo ves la línea cambiada.

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

La línea cambiada es la de DB_NAME, en la línea 23.

Si hay varios valores que cambiar, encadena scripts con -e y ejecútalos de una vez.

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' );

Si escribes -i y -e juntos como [-ie], la e se lee como parte del nombre de la copia, y apareció un archivo wp-config.phpe como el de abajo.

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 escribe el contenido editado en un archivo nuevo y luego lo renombra al nombre original, así que el número de inode del archivo cambia entre antes y después de ejecutar.

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

El número de inode, que era 207618887 antes de ejecutar, cambió a 207618883.

Si el archivo no existe o te falta el nombre del archivo, termina con el error de abajo y no cambia ningún archivo.

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️⃣ Expresiones regulares de sed, cambio de delimitador y opciones

🔲 Expresiones regulares y cambio de delimitador

Si cambias un valor con barras, como una ruta, el delimitador del comando s se mezcla con las barras del valor, así que cada barra del valor necesita una barra invertida.

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

El carácter justo después de s es el delimitador, así que si lo cambias por |, que no está en el valor, obtienes el mismo resultado sin barras invertidas.

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

El punto (.) de un patrón coincide con cualquier carácter. Abajo está el resultado de un patrón que busca example.com y también cambió exampleXcom.

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

Para buscar un punto literal, pon una barra invertida delante.

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

Lo que va entre paréntesis se recupera en la cadena nueva con [\1]. Con -E, los paréntesis y + se usan sin barras invertidas. Abajo está el resultado de conservar el número tras listen y añadir default_server.

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

Si ejecutas el mismo script sin -E, los paréntesis se leen como texto y sale un error de que no hay grupo que recuperar. Para trabajar sin -E, pon barras invertidas en los paréntesis y en +.

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;

[&] en la cadena nueva significa todo el texto que coincidió con el patrón, así que puedes poner # delante de esa parte y convertir la línea en comentario.

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

🔲 Opciones del comando sed

📌 Opciones principales: resultados de este artículo

OpciónTareaResultado en este artículo
-nDesactiva la impresión automática e imprime solo las líneas seleccionadas con psed -n '23p' muestra solo la línea 23; sin -n, 2p imprime la línea 2 dos veces
-iGuarda el resultado en el archivo original en lugar de la pantalla (el texto justo después se añade al final del nombre de la copia)-i.bak crea wp-config.php.bak; el número de inode cambia tras ejecutar
-eEncadena varios scripts y los ejecuta de una vezDB_USER y DB_PASSWORD cambian a la vez; escrito junto como -ie, aparece la copia wp-config.phpe
-EUsa expresiones regulares extendidas (sin barras invertidas en paréntesis y +)Imprime listen 80 default_server;, y el mismo script sin -E da el error [invalid reference]
--follow-symlinksJunto con -i, edita el archivo original al que apunta el enlaceSin ella, un archivo normal ocupa el lugar del enlace y el original no cambia; con ella, cambia el valor original

📎 Otras opciones: según el manual oficial

OpciónTarea
-fLee el script de un archivo y lo ejecuta
-rExpresiones regulares extendidas, igual que -E (-E es más portable)
-sProcesa cada archivo por separado en lugar de como uno solo continuo
-zSepara las líneas con el carácter nulo en lugar del salto de línea
-uLee la entrada en cantidades pequeñas y vacía la salida con más frecuencia
--posixDesactiva todas las extensiones de GNU
--debugMuestra el proceso de ejecución de forma detallada

🔲 Simulador del comando sed

La carpeta de trabajo del simulador de abajo tiene una copia de wp-config.php y example.conf. Puedes escribir tú mismo los comandos vistos hasta ahora y comprobar los archivos cambiados con -i usando ls -l y diff.

Simulador del comando sedGNU sed
[root@server work]#
Con las teclas ↑↓ recuperas los comandos que escribiste antes.

🔢 FAQ & contenido recomendado

wp-config-sample.php de WordPress tiene finales de línea CRLF, así que justo antes del fin de línea hay un [\r] invisible. Con [/false );$/] no salió ninguna línea, y en una copia a la que se quitó [\r] con [s/\r$//], el mismo patrón encontró la línea WP_DEBUG.

-i crea un archivo normal nuevo en el lugar del enlace y guarda ahí, así que el original al que apuntaba el enlace no cambió. Para editar el archivo original, indica también [--follow-symlinks]. En ese caso el enlace siguió igual y cambió el valor original.

Aunque definas la variable con NEW=wp_user, entre comillas simples el shell no la expande y [$NEW] entra como texto literal. Al envolver el script en comillas dobles, el shell expandió primero la variable y wp_user entró en lugar de [$NEW].

🧭 Contenido recomendado sobre comandos de texto 9 artículos · 2 referencias
🗂️ Comandos para ver y editar texto
📄 Comando grep 📄 Comando sort 📄 Comando uniq 📄 Comando tee 📄 Comando sed
📄 Comando cat 📄 Comando less 📄 Comandos head y tail 📄 Comandos vi y vim

ℹ️ Aviso de afiliados
El contenido de este sitio incluye enlaces de afiliado. Cuando un visitante compra un producto o servicio a través de uno de ellos, el sitio recibe una comisión del vendedor. El importe que paga el comprador(baja durante las promociones ↓)no aumenta. Los precios, descuentos y existencias publicados corresponden al momento de redacción y pueden variar, así que confírmalos con el vendedor antes de comprar. Los productos se eligen y evalúan con criterios propios, y las comisiones no influyen en el orden ni en el contenido de las reseñas.

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *

Demuestra que eres humano: 3   +   4   =