BREAKING NEWS

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.

 
Eliminar caracteres al principio y al final de una línea.


Eliminar el primer caracter de una expresión o cada línea de un archivo, sea cual sea.
# sed 's/^.//g'
Ejemplo:
(10.0.4.38)
(10.0.4.40)
(10.0.4.41)

El resultado de ejecutar el comando es:
10.0.4.38)
10.0.4.40)
10.0.4.41)


Si lo que se desea es eliminar el último caracter de una expresión o cada línea de un archivo,
# sed 's/.$//g'
Ejemplo:
(10.0.4.196)
(10.0.4.201)
(10.0.4.207)
(10.0.4.220)
(10.0.4.248)

El resultado es el siguiente:
(10.0.4.196
(10.0.4.201
(10.0.4.207
(10.0.4.220
(10.0.4.248

Eliminando tanto el primer como el último caracter de cada línea.
# sed 's/^.\|.$//g'
Ejemplo:
(10.0.4.196)
(10.0.4.201)
(10.0.4.207)
(10.0.4.220)
(10.0.4.248)

El resultado de ejecutar el comando es:
10.0.4.196
10.0.4.201
10.0.4.207
10.0.4.220
10.0.4.248

Otro ejemplo: Supongamos que deseamos obtener de un archivo de texto unicamente los direccionamientos IP's, pero el archivo tiene el siguiente formato.

ip-10-0-0-16.ec2.internal (10.0.0.16)
ip-10-0-0-22.ec2.internal (10.0.0.22)
ip-10-0-0-37.ec2.internal (10.0.0.37)
ip-10-0-0-41.ec2.internal (10.0.0.41)
ip-10-0-0-42.ec2.internal (10.0.0.42)
ip-10-0-0-73.ec2.internal (10.0.0.73)
ip-10-0-0-84.ec2.internal (10.0.0.84)

Existen diferentes maneras de obtener unicamente los direccionamientos IP's sin el parentesis, para ello haremos uso de los comandos cat, cut y sed.

# cat archivo.txt |cut -d" " -f2- | sed 's/^.\|.$//g'
Y el resultado es:
10.0.0.16
10.0.0.22
10.0.0.37
10.0.0.41
10.0.0.42
10.0.0.73
10.0.0.84

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:

Reemplaza la cadena que inicia con la palabra "Host solaris8" por la cadena "Host Solaris9" ejemplo anterior.
# 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'

Cambiar de /usr/bin/ --> /usr/local/bin/
# sed 's/\/usr\/bin\//\/usr\/local\/bin\//g'

Cambiar /gnt/runtime/runtime1/runtime/  por  /gnt/runtime/
# sed  's/\/gnt\/runtime\/runtime1\/runtime\//\/gnt\/runtime\//g'


Cambiar /gnt/athenea/athenea4/  por  /gnt/code/athenea4/
# s/\/gnt\/athenea\/athenea4\//\/gnt\/code\/athenea4\//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 :)