Normalmente un administrador de sistemas tiene que modificar archivos de configuración, tablas y otros archivos de texto repetidamente para realizar cambios y ajustes. Gnu/Linux trae una gran cantidad de editores de texto tanto para la línea de comandos (emacs, vi, nano, etc) como gráfico (gedit, kate, etc)

Este tipo de editores son útiles cuando vamos a editar un par de textos, pero que pasa cuando queremos modificar una gran cantidad de archivos o queremos automatizar modificaciones a través de un script, en este caso es que entra el comando sed, como sabemos sed viene incluida por defecto en la gran mayoría de las distribuciones de GNU/Linux.


Esta es la definición de la Free Software Fundation acerca de sed:

Sed (streams editor) no es realmente un verdadero editor o procesador de texto. En cambio es utilizado para filtrar texto, por ejemplo, toma la entrada de texto y realiza sobre ella alguna operación (o conjunto de operaciones) y imprime el texto modificado.

Sed es usado generalmente para extraer parte de un archivo usando un patron o sustituyendo múltiples ocurrencias de una cadena de texto dentro de un archivo.



Expresiones regulares

Las expresiones regulares son un grupo de caracteres y reglas que sirven para filtrar patrones de letras, números, símbolos y condiciones como por ejemplo al principio de la línea o al final, un carácter o varios, etc.



Caracteres especiales:







Para entender un poco mejor vamos a ver unos ejemplos todos estos los pueden colocar dentro de las ' ' para filtrar según sea el caso.




Utilizar Expresiones Regulares

Como casi todos los comandos en Gnu/Linux sed también soporta expresiones regulares las cuales son muy útiles para filtrar patrones, al utilizar estas expresiones regulares es que podemos utilizar sed a su máximo potencial.

Supongamos que queremos eliminar todas las líneas en blanco de un archivo, nos movemos a el directorio /tmp para hacer las pruebas.


mkdir /tmp/pruebas
cd /tmp/pruebas
nano prueba




Ingresamos el siguiente contenido:

 #########################
############################

alband es usuario de Taringa
desde el 3 de Junio del 2008
Ruta Gral Aquino N 5
4ta Villa Industrial 
Ciudad de Asunción, C.P. 1160
fin del texto 

###########################
 #########################







Guardamos los cambios y salimos de nano, luego escribimos en la terminal

sed -e '/^$/d' prueba






En el comando la expresión regular es /^$/ esta expresión quiere decir todas las líneas que estén en blanco. Muy útil cuando queremos ver un archivo que tiene muchas líneas en blanco y queremos compactar todo para verlo mejor.


Si queremos guardar el resultado en un nuevo archivo en vez de que sólo lo imprima en pantalla debemos redireccionar la salida ( > ) hacia un nuevo archivo :

sed -e '/^$/d' prueba > prueba2


Otro comando útil es para eliminar los comentarios que comienzan normalmente con # en los archivos de configuración para eliminarlos ejecutamos:

sed -e '/^#/d' prueba





Esto elimina todas las líneas que comienzan con #.



Otro de los usos interesantes es borrar los espacios al comienzo de cada línea:

sed 's/^ *//g' prueba







En el siguiente ejemplo se reemplazan los espacios por tabuladores a lo largo de todas las líneas:

sed 's/\ /\t/g' prueba








En el siguiente ejemplo se reemplazan solo el primer espacio de cada línea por un tabulador, la diferencia con el comando anterior es muy evidente:

sed 's/\ /\t/' prueba








Imprimir línea o conjuntos de líneas

Hasta ahora solo hemos borrado líneas pero que tal si queremos que imprima las líneas que coinciden con nuestro filtro. Vamos a ver un ejemplo supongamos que queremos imprimir las líneas que comienzan con d y f minúsculas entonces ejecutamos lo siguiente:

sed -n -e '/^[df]/p' prueba






Tenemos dos elementos nuevos en nuestro comando, el primero es la opción -n que hace que sólo se imprima lo que coincida con nuestro filtro y hemos cambiado el comando ‘d’ por el comando ‘p’ (print) que dice que imprima el espacio del patrón.



Más de Expresiones Regulares

Ahora vamos a hacer algo más complejo vamos a mezclar dos expresiones regulares, supongamos que de nuestro archivo prueba queremos imprimir desde la línea que comienza con Gral hasta la línea que finaliza con Ciudad. para esto ejecutamos:

sed -n -e '/Gral/,/Ciudad/p' prueba




Cuando se utiliza de esta forma sed filtrará cualquier línea que comience con la primera expresión, en este caso "Ruta", hasta que consiga la siguiente expresión, en este caso "Ciudad", esto nos permite imprimir bloques de texto delimitados por ciertas palabras o expresiones.



Para reemplazar texto se utiliza el modelo 's/texto-viejo/nuevo-texto/'
En el siguiente ejemplo se reemplazará el 2 por el 9:

sed 's/2/9/' prueba





Al ejecutar el comando anterior, se sustituye la primera cadena que encuentra por la segunda. Pero, si lo que queremos es sustituir todas las cadenas que encuentre, en cada una de las líneas, añadimos el parámetro g:


sed 's/2/9/g' prueba






Por otra parte, también podemos hacer que sustituya la cadena1 por la cadena2 en un número de línea concreto:

sed '6 s/Ruta/Avenida/g' prueba







Con cadenas de texto normales la cosa es sencilla, se complica un poco cuando lo que hay que sustituir son caracteres especiales como el tabulador: \t o el carácter de nueva línea: \n.

Pero veamos como tampoco es tan complicado, vamos a sustituir el carácter separador por otro carácter separador, como por ejemplo el punto y coma ;

Vamos a agregar una línea nueva:

echo -e "sustituir\tel tabulador" >> prueba

Verificamos que se inserto el texto

more prueba





y usamos el comando en cuestión

sed 's/\t/;/g' prueba






Si se quiere convertir a doble espacio la salida del archivo prueba, utilice el siguiente mandato:

sed G prueba







Vamos a guardar esta salida en un archivo nuevo y lo llamamos prueba2, utilice lo siguiente:

sed G prueba > prueba2

Si se desea eliminar el doble espacio del archivo prueba2, se utiliza lo siguiente:

sed 'n;d' prueba2

La salida devolverá lo siguiente:







Si se quiere convertir a doble espacio la salida del archivo prueba, utilice el siguiente mandato:

sed 'G;G' prueba

La salida devolverá lo siguiente:







Si se quiere agregar una línea en blanco arriba de toda línea que contenga la expresión regular Gral, se utiliza lo siguiente:

sed '/Gral/{x;p;x;}' prueba






Si se quiere agregar una línea en blanco debajo de toda línea que contenga la expresión regular 4, se utiliza lo siguiente:

sed '/4/G' prueba

La salida devolverá lo siguiente:






Si se quiere agregar una línea en blanco arriba y debajo de toda línea que contenga la expresión regular 4, se utiliza lo siguiente:

sed '/4/{x;p;x;G;}' prueba

La salida devolverá lo siguiente:






La siguiente línea añade 5 espacios al inicio de cada línea:

sed 's/^/     /' prueba

La salida devolverá lo siguiente:






El siguiente mandato solo imprime la primera línea del archivo prueba:

sed q prueba

La salida devolverá lo siguiente:






El siguiente mandato solo imprime las primeras dos líneas del archivo prueba:

sed 2q prueba

La salida devolverá lo siguiente:





El siguiente mandato solo muestra las últimas tres líneas del archivo prueba:

sed -e :a -e '$q;N;4,$D;ba' prueba


La salida devolverá lo siguiente:






El siguiente mandato solo mostrará las líneas que incluyen el 8:

sed '/8/!d' prueba

La salida devolverá lo siguiente:






El siguiente mandato solo mostrará las líneas que NO incluyen 8:

sed '/8/d' prueba

La salida devolverá lo siguiente:






El siguiente mandato pide mostrar la linea que está inmediatamente después de la expresión Ruta, pero no la línea en si que incluye Ruta:

sed -n '/Ruta/{n;p;}' prueba

La salida devolverá lo siguiente:






El siguiente mandato pide mostrar la linea que está inmediatamente antes de la expresión Ruta, pero no la línea en si que incluye Ruta:

sed -n '/Ruta/{g;1!p;};h' prueba

La salida devolverá lo siguiente:






Para borrar una línea hacemos lo siguiente:

Podemos indicar un número de línea concreto:

sed '1d' prueba

Podemos indicar un intervalo de líneas a borrar. Por ejemplo:

sed '3,5d' prueba




También podemos indicar que queremos borrar desde una determinada línea en adelante:

sed '3,$d' prueba





Utilizar variables dentro de sed

Si necesitamos utilizar variables dentro de la ejecución del comando sed, si lo hacemos del modo "estandar" no funcionará correctamente:

sed 's/Junio/$(date +%B)/g' prueba




El resultado no es el esperado, será necesario utilizar comillas dobles en lugar de comillas simples, de ese modo funcionará correctamente:


sed "s/Junio/$(date +%B)/g" prueba

De esta forma cambia correctamente lo que diga Junio por el mes actual