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:
regex
por el correspondiente texto
en la línea corriente. Parámetros adicionales:
regex
(si regex está al menos 3 veces presente en la línearegex
regex
en la línea 3regex
entre las líneas 3 y 7regex
en todo el archivoEl 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.
regex
regex
)Opciones habituales:
regex
regex
regex
regex
regex
regex
con colorregex
y las NUM
líneas siguientes (after)NUM
anteriores (before)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
a
y la d
o números entre 6 y 9Anclas: 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
n
vecesm
vecesn
y m
vecesConcatenació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 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