GREP y SED

Antecedentes: editor de text ED

ed es un editor de línea. Fue desarrollado en una época en la que las terminales de computadora (teclado y pantalla) no eran lo más corriente. Usualmente se utilizaba una teletipo (una suerte de máquina de escribir: teclado con impresión en papel fanfold),para comunicarse con la computadora y por lo tanto no era posible desplegar datos en una pantalla. Para ahorrar papel, el contenido de un archivo se ingresaba una línea por vez y se empleaban comandos sofisticados para realizar la edición. De esta aplicación surgen maneras muy inteligentes y eficientes de procesar textos. Muchas de las ideas incorporadas a ed para trabajar eficientemente con textos migrarían a programas como vi, grep y sed.

Referencias:

Tutorial muy básico de ed:

Ed tiene 2 modos: comando e inserción

En el modo comando, la sintaxis para ingresar comandos es:

[ dirección[,dirección]]comando[parámetros]

donde lo que aparece entre paréntesis rectos es opcional

Los comandos suelen limitarse a una letra. Las direcciones corresponden a números de línea, los parámetros son datos adicionales que en ocasiones el comando requiere.

ed siempre arranca en modo comando. Para pasar a modo insertar o agregar, deben usarse los comandos i o a. Si se usa el comando i, se inserta texto antes de la línea corriente. Si se usa el comando a, se agrega texto luego de la línea corriente. Para terminar de insertar o agregar texto, se debe insertar una . aislado en una línea. Eso hace que ed pase del modo inserción a modo comando nuevamente.

Sólo es posible ingresar comandos en el modo comando. Mientras que se está en el modo inserción, todo el texto que se inserte pasa a formar parte del archivo que se esté editando.

Mientras se está editando el archivo, el texto existe en un “buffer” (podemos pensarlo como un área de trabajo, en la memoria de la computadora). Para salvar ese texto usamos el comando w:

Para salir de ed podemos usar el comando q. Si no queremos salvar el contenido del archivo, pero queremos salir de ed, podemos forzar la salida con Q.

Para distinguir cuando estamos en modo comando o modo inserción, podemos activar un prompt, con el comando P. de esa manera aparece un * (asterisco), que marca que estamos en modo comando.

Direccionamiento:

Cómo elegimos la línea corriente:

Por defecto, cualquier comando que se ejecute, tiene efecto únicamente sobre la línea corriente. Para que el comando actúe sobre varias líneas, hay que especificar un rango de direcciones: [dirección[,dirección]]

Rangos de líneas y cambio de línea corriente:

Comando habituales:

Cambiando una línea:

Borrando una línea (o rango de líneas):

Moviendo líneas:

Sustituyendo texto:

Parámetros adicionales:

GREP

El comando g/re/p de ed es el origen del nombre del comando grep. Sirve para buscar dentro de uno o más archivos, líneas que contengan una determinada expresión regular.

grep "regex" archivo
grep -e "regex" archivo

grep puede invocarse también como egrep fgrep o rgrep.

Opciones habituales:

Expresiones Regulares

La expresión regular más sencilla es un texto cualquiera.

grep "texto" archivo
grep -i "texto" archivo

Si usamos fgrep o grep -F, entonces se puede emplear cualquier caracter en en el “texto” que se busca. De lo contrario, hay algunos caracteres que tienen significado especial (metacaracteres). Si se desea incluir un metacaracter en la búsqueda, hay que anular su significado, antecediéndolo con \.

Metacaracteres y su uso: 1) conjuntos de caracteres:

grep if if.txt

grep "[iI]f" if.txt
grep -i if if.txt

Anclas: comienzo o fin de una línea:

grep -i if if.txt
grep -i "^if" if.txt

Repetición: metacaracteres que se aplican a una regex que le antecede

Concatenación: las regex se pueden concatenar y valen por la unión de ambas regex

grep "[iI][fF]" if.txt

Alternación: usando | es posible especificar regex alternativas (equivale al operador lógico OR).

egrep "IF|life" if.txt
egrep "I[fF]|life" if.txt

Precedencia: repetición > concatenación > alternación. La precedencia se puede cambiar usando paréntesis ( ) para agrupar sub-expresiones regulares.

Expresiones regulares básicas vs. extendidas: en modo básico (por defecto), los metacaracteres ?, +, {, |, ( y ) no funcionan, deben usarse precedidos por \. Es preferible siempre usar la grep -E o egrep

Ejemplo más complejo: extraer emails de un mailbox

Si quiero extraer líneas con direcciones de email:

grep -E  "\b[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,6}\b" mbox

Si sólo quiero las direcciones de email, uso la opción '-o':

grep -E -o "\b[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,6}\b" mbox

Ejemplo: extraer número IP de un mailbox

grep -E -o "([0-9]{1,3}[\.]){3}[0-9]{1,3}" mbox

Ejemplo de PES (Potential Energy Surface):

cálculo de HF: hf.out

Extraigo las distancias:

grep "^ !       R1 " hf.out|grep "DE/DX"|cut -b 22-25 >nada1

Otra forma de hacer esto:

grep '^ !.*DE/DX' hf.out|tr -s " " "\t"|cut -f4

Extraigo las energías:

grep '^ SCF Done:  ' hf.out|cut -b 26-35 >nada2

Junto ambas columnas:

paste nada1 nada2

Finalmente procesamos los datos con pyxplot para generar la curva de PES

SED: Stream Editor

sed es un descendiente directo de ed, sólo que en lugar de trabajar interactivamente con el editor, sed ejecuta uno o más comandos de ed en un stream de bytes que recibe por stdin o desde un archivo, volcando a stdout el resultado. Básicamente todo lo que se puede hacer en ed se puede hacer con sed.

Ejemplos:

sed -nr '/if/p' if.txt
sed -nr '/[iI][fF]/p' if.txt
sed -nr '/^[iI][fF]/p' if.txt
sed -rn 's/If/IF/' if.txt
sed -rn 's/If/IF/p' if.txt
sed -r  's/^I[fF]/SI/' if.txt
sed -r  's/^ *$/    --------/' if.txt

Volvemos al ejemplo del HF: en el ejemplo que vimos usamos cut para extraer las columnas 26 a 35

grep '^ SCF Done: ' hf.out | cut -b 26-35 

pero si sustituimos los espacios en blanco por tabuladores, entonces podemos usar cut haciendo referencia al campo (-f):

grep '^ SCF Done: ' hf.out | sed 's/^ //; s/  */\t/g' | cut -f5

Ojo con los metacaracteres: a veces debo usar regex extendido:

grep '^ SCF Done: ' hf.out | sed -r 's/^ //; s/ +/\t/g' | cut -f5