Linuxsc.net - Uso básico del comando SED, (reemplazar cadenas en archivos con sed)

Uso básico del comando SED, (reemplazar cadenas en archivos con sed)

¿Qué es sed?

SED (Stream EDitor) es un editor de flujos y archivos de forma no interactiva. Permite modificar el contenido de las diferentes líneas de un archivo en base a una serie de comandos o un archivo de comandos (-f archivo_comandos).

Sed recibe por stdin (o vía archivo) una serie de líneas para manipular, y aplica a cada una de ellas los comandos que le especifiquemos a todas ellas, a un rango de las mismas, o a las que cumplan alguna condición.

Por ejemplo:

Sustituir apariciones de cadena1 por cadena2 en todo el archivo:
# cat archivo | sed 's/cadena1/cadena2/g'

# cat saludo.txt
hola
maldito
mundo

# sed 's/maldito/bendito/' animal.txt
hola
bendito
mundo

Sustituir apariciones de cadena1 por cadena2 en las líneas 1 a 10:
# comando | sed '1,10 s/cadena1/cadena2/g'

Eliminar las líneas 2 a 7 del archivo
# sed '2,7 d' archivo > archivo2

Eliminar la linea 2 del archivo saludo:
# sed '2d' saludo.txt
hola
mundo

Sintaxis

La sintaxis de sed es:

# sed [-ns] '[direccion] instruccion argumentos'

Donde:

  • [direccion] es opcional, siendo un número de línea (N), rango de números de línea (N,M) o búsqueda de regexp (/cadena/) indicando el ámbito de actuación de las instrucciones. Si no se especifica [direccion], se actúa sobre todas las líneas del flujo.

 

  • Instruccion puede ser:
  • i = Insertar línea antes de la línea actual.
  • a = Insertar línea después de la línea actual.
  • c = Cambiar línea actual.
  • d = Borrar línea actual.
  • p = Imprimir línea actual en stdout.
  • s = Sustituir cadena en línea actual.
  • r archivo = Añadir contenido de “archivo” a la línea actual.
  • w archivo = Escribir salida a un archivo.
  • ! = Aplicar instrucción a las líneas no seleccionadas por la condición.
  • q = Finalizar procesamiento del archivo.
  • -n: No mostrar por stdout las líneas que están siendo procesadas.
  • -s: Tratar todos los archivos entrantes como flujos separados.

 

Ejemplos de sustitución


Se sabe que el comando "sed -i '/s/palabra-vieja/palabra-nueva/g' *.txt" o "sed -i '/s/111.222.333.4/555.666.777.8/g' pri.*" reemplaza todas las ocurrencias de la palabra vieja por palabra nueva o todas las IPs 111.222.333.4  por 555.666.777.8 en todos los archivos:

sed -i 's/Pepe/Jose/g' *.txt
sed -i 's/Manolo/Manuel/g' *.txt
sed -i 's/Nacho/Ignacio/g' *.txt
sed -i 's/Inma/Inmaculada/g' *.txt
sed -i 's/111.222.333.4/555.666.777.8/g' pri.*


Reemplazar cadenas:
# sed 's/^Host solaris8/Host solaris9/g' archivo > archivo2

Reemplazar cadenas sólo en las lineas que contentan una cadena:
# sed '/cadena_a_buscar/ s/vieja/nueva/g' archivo > archivo2

Reemplazar cadenas sólo en en determinadas líneas:
# sed '5,6 s/vieja/nueva/g' archivo > archivo2

Reemplazar multiples cadenas (A o B):
# sed 's/cadenasrc1\|cadenasrc2/cadena_nueva/g'

Sustituir líneas completas (c) que cumplan o no un patrón:
# echo -e "linea 1\nlinea 2" | sed '/1/ cPrueba'
Prueba
linea 2
# echo -e "linea X 1\nlinea 2" | sed '/1/ !cPrueba'
linea 1
Prueba

Ejemplos de Inserción

Insertar 3 espacios en blanco al principio de cada línea:
# sed 's/^/   /' archivo

Añadir una línea antes o despues del final de un archivo ($=última línea):
# sed -e '$i Prueba' archivo > archivo2
# sed -e '$a Prueba' archivo > archivo2

Insertar una linea en blanco detras de cada linea que cumpla una regex:
# cat archivo | sed '/cadena/G'

Insertar una linea en blanco antes y despuess de cada linea que cumpla una regex:
# cat archivo | sed '/cadena/{x;p;x;G;}'

Ejemplos de Selección/Visualización


Ver un rango concreto de líneas de un archivo:
# cat -n fich2 | sed -n '2,3 p'
2    linea 2
3    linea 3
(Con cat -n, el comando cat agrega el número de línea).
(Con sed -n, no se imprime nada por pantalla, salvo 2,3p).

Ver un rango concreto de líneas de varios archivos:
# sed '2,3 p' *
linea 2 archivo 1
linea 3 archivo 1
linea 2 archivo 2
linea 3 archivo 2
(-s = no tratar como flujo sino como archivos separados)

Sólo mostrar la primera linea de un archivo:
# sed -n '1p' archivo > archivo2.txt
No mostrar la primera linea de un archivo:
# sed '1d' archivo > archivo2.txt


Mostrar la primera/ultima línea de un archivo:
# sed -n '1p' archivo
# sed -n '$p' archivo

Mostrar desde una expresión regular hasta el final de archivo:
# sed -n '/regexp/,$p' archivo

Ejemplos de Borrado

Eliminar un rango concreto de líneas de un archivo:
# sed '2,4 d' archivo > archivo2.txt

Eliminar todas las líneas de un archivo excepto un rango:
# sed '2,4 !d' archivo > archivo2.txt

Eliminar las líneas que contentan una cadena:
# sed '/cadena/ d' archivo > archivo2.txt
# sed '/^cadena/ d' archivo > archivo2.txt
# sed '/^cadena$/ d' archivo > archivo2.txt

Eliminar líneas en blanco (variación del anterior):
# comando | sed '/^$/ d'
# sed '/^$/ d' archivo > archivo2.txt

Eliminar múltiples líneas en blanco consecutivas dejando sólo 1:
# sed '/./,/^$/!d' archivo

Añadir una línea después de cada línea:
# echo -e "linea 1\nlinea 2" | sed 'aPrueba'
linea 1
Prueba
linea 2
Prueba

Eliminar espacios al principio de línea:
# sed 's/^ *//g' archivo

Eliminar todos los espacios que haya al final de cada línea:
# sed 's/ *$//' archivo

Eliminar espacios sobrantes a principio y final de línea, o ambos:
# sed 's/^[ \t]*//' archivo
# sed 's/[ \t]*$//' archivo
# sed 's/^[ \t]*//;s/[ \t]*$//' archivo


Eliminar tags HTML:
sed -e :a -e 's/<[^>]*>//g;/

Uso de salida selectiva

Salir a nuestra voluntad antes de acabar el archivo:
# sed -e '/uno/ s/uno/1/' -e '/salir/ q' archivo > archivo2.txt
# sed 10q archivo
# sed q archivo


Equivalencia de -e con ";":
# sed -e '/AAA/b' -e '/BBB/b' -e 'd'  ==  sed '/AAA/b;/BBB/b;d'

Usar 'q' apropiadamente reduce tiempo de procesamiento:
# sed -n '10,20p' archivo
# sed -n '21q;10,20p' archivo  -> Más rápido que el anterior.


Suerte :)