En esta serie de 3 partes vamos a presentar el comando sed, uno de los comandos más poderosos en Linux para manipular texto y una herramienta muy valiosa para aquellos que administran sistemas Linux.
Bienvenido SED
Normalmente un administrador de sistemas tiene que modificar archivos de configuración, tablas y otros archivos de texto repetidamente para realizar cambios y ajustes. Linux trae una gran cantidad de editores de texto tanto para la línea de comandos (emacs, vim, 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.
La versión GNU de sed viene incluida por defecto en la gran mayoría (sino en todas) las distribuciones de GNU/Linux.
En 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 típicamente para extraer parte de un archivo usando un patron o sustituyendo múltiples ocurrencias de una cadena de texto dentro de un archivo.
Al momento de escribir este tutorial la última versión estable de GNU sed (sed de ahora en adelante) es la 4.2.1. Para ver la versión que tienes ejecuta en el terminal:
sed --version
Lo Básico de Sed
El formato básico del comando sed es:
sed opciones [script] [archivo(s)]
Características principales de sed:
- Si no se le da ningún archivo sed toma la entrada estandar (stdin).
- Sed filtra línea por línea, no letra por letra.
- La salida por defecto de sed es la salida estándar (stdout).
Para los ejemplos vamos a trabajar con el siguiente texto es una cita de Carl Sagan creen un archivo llamado texto1 con el siguiente contenido
Vivimos en una sociedad profundamente
dependiente de la ciencia y la tecnología y
en la que nadie sabe nada de estos temas.
Ello constituye una fórmula segura para el desastre.
Noten que el texto tiene líneas en blanco entre cada línea de texto, no las borren ya nos encargaremos de ellas.
Las acciones principales de sed son las siguientes:
Borrar línea o conjunto de líneas
Ejecuten el siguiente comando:
sed -e '1d' texto1
Deben ver en el terminal el texto sin la primera línea, vamos a analizar un poco el comando, le dimos la opción -e que es para editar, luego colocamos ‘1d’ que le dice a sed que tome la primera ocurrencia de línea y la borre (d=delete) y luego le pasamos el nombre del archivo texto1. Noten que sed no modifica el archivo original como tal, simplemente nos muestra la modificación en la salida estándar (stdout), si queremos guardar la modificación en un nuevo archivo debemos redireccionar la salida lo cual lo veremos más adelante.
Ahora que pasa si queremos borrar más de una línea, pues afortunadamente sed permite que le demos rangos, si queremos borrar de la línea 2 a la línea 5 ejecutamos:
sed -e '2,5d' texto1
Este comando es muy parecido al anterior solo que en esta oportunidad le estamos dando un rango de la línea 2 a la línea 5. Noten que sed toma en cuenta las líneas en blanco también.
Utilizar Expresiones Regulares
Como casi todos los comandos en 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.
Vamos a ver un ejemplo y después entramos en detalle. Supongamos que queremos eliminar todas las líneas en blanco de nuestro archivo de texto1 utilizaríamos el siguiente comando:
sed -e '/^$/d' texto1
Lo único que hemos cambiado en el comando es la expresión regular /^$/ 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.
Otro comando útil es para eliminar los comentarios que comienzan normalmente con # en los archivos de configuración para eliminarlos ejecutamos:
sed -e '/^#/d' /etc/services | less
Esto elimina todas las líneas que comienzan con #. No se preocupen por modificar el archivo como les dije anteriormente sed imprime el resultado en la salida estándar (stdout) y no en el archivo.
Vamos a dar un pequeño repaso de expresiones regulares.
Las expresiones regulares son un grupo de caractéres 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 fina, un caracter o varios, etc.
Caracteres especiales:
Caracter | Descripción |
^ | Corresponde al inicio de la línea |
$ | Corresponde al final de la línea |
. | Filtra un sólo caracter |
* | Filtra cero o más caracteres |
[] | Filtra todo el rango dentro de los [] |
Para entender un poco mejor vamos a ver unos ejemplos todos estos los pueden colocar dentro de las ‘ ‘ en el comando sed para filtrar según sea el caso:
Expresión Regular | Descripción |
/./ | Filtra cualquier línea que tenga al menos 1 caracter |
/…/ | Filtra cualquier línea que tenga al menos 3 caracter |
/^#/ | Filtra cualquier línea que comience con # |
/^$/ | Filtra cualquier línea en blanco |
/)$/ | Filtra cualquier línea que termine con ‘)’ (sin espacios) |
/) *$/ | Filtra cualquier línea que termine con ‘)’ seguido por cero o más espacios |
/[xyz]/ | Filtra cualquier linea que contenga las letras ‘x’ ‘y’ o ‘z’ en minúsculas |
/^[DEF]/ | Filtra cualquier línea que comience con ‘D’, ‘E’ o ‘F’ |
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 e minúsculas entonces ejecutamos lo siguiente:
sed -n -e '/^[de]/p' texto1
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.
Si ejecutan el comando anterior deberían obtener sólo dos líneas.
Más de Expresiones Regulares
Ahora vamos a hacer algo más complejo vamos a mezclar dos expresiones regulares, supongamos que de nuestro archivo texto1 queremos imprimir desde la línea que comienza con Vivimos hasta la línea que finaliza con tecnología. para esto ejecutamos:
sed -n -e '/Vivimos/,/tecnología/p' texto1
Cuando se utiliza de esta forma sed filtrará cualquier línea que comience con la primera expresión, en este caso ‘Vivimos’, hasta que consiga la siguiente expresión, en este caso ‘tecnología’, esto nos permite imprimir bloques de texto delimitados por ciertas palabras o expresiones.
Por último si para cualquiera de los comandos anteriores queremos guardar el resultado en un nuevo archivo en vez de que sólo lo imprima en pantalla debemos redireccionar la salida (>) hacia el nuevo archivo por ejemplo:
sed -n -e '/Vivimos/,/tecnología/p' texto1 > texto2
Lo que acabamos de ver es lo básico de sed aún queda mucho más
Cualquier duda o sugerencias por favor dejen su comentario