PDF de programación - Sed - Introducción a SED - Parte II

Imágen de pdf Sed - Introducción a SED - Parte II

Sed - Introducción a SED - Parte IIgráfica de visualizaciones

Publicado el 28 de Marzo del 2018
281 visualizaciones desde el 28 de Marzo del 2018
161,0 KB
17 paginas
Creado hace 5a (13/06/2014)
Sed – Introducción a SED – Parte II

Junio 2014



SED - The Stream EDitor - Part II

Este articulo es una introducción al uso del editor de flujo “SED”. El articulo intenta cubrir ciertas
funcionalidades poco conocidas, por no decir “casi desconocidas”, que hacen de “SED” una
herramienta indispensable en la caja de herramientas de todo usuario de Linux que desea dominar el
procesamiento de ficheros vía una consola y un shell.

Índice parte II

Los delimitadores

Delimitadores de comandos
Delimitador de patrón

El metacaracter &
Las subexpresiones y las referencias hacia atrás

Las subexpresiones
Las referencias hacia atrás
Expresión regular precedente

La negación
La agrupación de comandos
El reemplazo de variables
Las expresiones regulares

Los caracteres de escape
Otros
Las clases de caracteres

Las diferentes versiones

Unix
Windows

Depuradores
¿Cuando no debo utilizar Sed?
Limites conocidos de las diferentes versiones
Referencias
Libros
Enlaces

Principiantes y conocedores
Avanzados
IRC

SED - The Stream EDitor - Part III



Los delimitadores



Delimitadores de comandos

De manera predeterminada, Sed utiliza como delimitador para su mecanismo de substitución la barra
oblicua "/" (slash):

sed 's/patrón/reemplazo/' fichero

Para la mayoría de casos, esta opción por defecto resulta suficiente, pero puede resultar un problema
si el patrón o la cadena de reemplazo también contienen uno o más slash(es) como en el caso de la
ruta de un archivo. Evidentemente puedes proteger los slashes anteponiéndoles un "\" ( anti-slash o
barra oblicua invertida), pero esto resulta una operación muy fastidiosa si el patrón (o la cadena de
reemplazo) contiene varios, volviendo la lectura del código bastante difícil:

sed 's/\/home\/jp\/Docs\/CCM\/SED/\/mnt\/servidor\/docs/' fichero

Hasta puede ser imposible si el patrón (o la cadena de reemplazo) es una variable que debe ser
interpretada:

var="/home/jp/Documentos/CCM/SED/"
sed 's/'$var'/\/mnt\/servidor\/docs/' fichero

o (expresión entre doble apóstrofes)

sed "s/$var/\/mnt\/servidor\/docs/" fichero

Felizmente, Sed permite reemplazar el delimitador por defecto con el carácter de nuestra elección
(#,|,!,§,etc.), siempre y cuando no forme parte del patrón (o la cadena de reemplazo):

sed 's#/home/jp/Docs/CCM/SED#/mnt/servidor/docs#' fichero

Este carácter puede ser cualquier letra siempre y cuando no este contenida en el patrón (o la cadena
de reemplazo):

echo "hola" | sed 'sZbZBZ'

Si utilizas el carácter "!" (signo de exclamación) como separador, debes encerrar la expresión
con apostrofes simples para que el shell no interprete el carácter "!" (empleado normalmente
para gestionar el historial de los comandos).

Delimitador de patrón

Como lo hemos visto, Sed utiliza un patrón, encerrado entre "/" (slash), para buscar coincidencias en
las líneas de un fichero. El slash utilizado por defecto, puede ser cambiado por cualquier otro carácter,
simplemente anteponiendo a la 1ra ocurrencia de este carácter un "\" (backslash). Tomemos el
ejemplo de una ruta como criterio de búsqueda. Bajo esta forma, vemos que la lectura del código no
es fácil:

sed -n '/\/home\/jp\/Docs\/CCM\/SED/p' fichero

Sin embargo, si utilizamos el carácter almohadilla "#" como delimitador, tendremos:

sed -n '\#/home/jp/Docs/CCM/SED#p' fichero



El metacaracter &

A menudo, el mecanismo de substitución se limita a buscar un patrón a fin de substituirlo por si mismo
y agregándole algo, por ejemplo, buscar la cadena "Sed the Stream EDitor" en un fichero y agregarle
"Sed the Stream EDitor (Editor de flujo)". Podríamos escribir:

sed 's/Sed the Stream EDitor/Sed the Stream EDitor (Editor de flujo)/g' fichero

El metacaracter "&" (Ampersand) nos permite reemplazar todas las cadenas de caracteres que

coinciden con el patrón (o la expresión regular) ingresado como 1er argumento. Aquí la noción
de 1er argumento no es muy explicita, pero se vera su importancia con las expresiones
regulares y en el capitulo de las “sub-expresiones”. Por lo tanto nuestro comando se escribirá

de esta manera:

sed 's/Sed the Stream EDitor/& (Editor de flujo)/g' fichero

Supongamos que tenemos que buscar todas las cadenas numéricas (1 o varias cifras consecutivas)
en un fichero y deseamos anteponer a cada una de estas cadenas "n° " (observa el espacio después
de el "°"). El comando seria:

sed 's/[0-9][0-9]*/n° &/g' fichero

Necesariamente se debe utilizar la expresión "\&" para obtener un "&" literal en una cadena de
reemplazo, si no se generarán errores.

Las subexpresiones y las referencias hacia atrás



Las subexpresiones

\(...\) Una subexpresión es una parte de una expresión regular, encerrada entre paréntesis, que
posteriormente podemos utilizar en la substitución. Los paréntesis deben ser protegidos con
backslashes, a menos que la opción “-r” haya sido empleada.

Las referencias hacia atrás

\1 \2 \5 Para referirnos a cada subexpresión en la cadena de reemplazo, utilizamos un número que
corresponde a la posición que ocupa en la expresión regular. Este número debe estar protegido por un
backslash. Únicamente podemos referirnos a 9 subexpresiones numeradas del \1 à \9. Estas
referencias también son llamadas “referencias hacia atrás”. A continuación algunos ejemplo con
nombre de ciudades francesas y su código postal correspondiente: Archivo de referencia:

$ cat plop
31000 Toulouse
34000 Montpellier
66000 Perpignan

En este ejemplo, la subexpresión "\([0-9]*\)" coincidirá con cualquier cadena numérica y es
referenciada por la referencia hacia atrás "\1":

$ sed 's/\([0-9]*\).*/\1/' plop
31000
34000
66000

Esta vez, buscamos las coincidencias de 2 subexpresiones, una numérica y la otra conteniendo el
resto de la línea, pero sin incluir el carácter de tabulación que separa el código postal del nombre de la
ciudad. Luego utilizamos la referencia hacia atrás "\1" (código postal) y "\2" (nombre de la ciudad) para
mostrar el resultado bajo la forma: nombre de la ciudad > código postal

$ sed 's/\([0-9]*\)\t\(.*\)/\2 > \1/' plop
Toulouse > 31000
Montpellier > 34000
Perpignan > 66000

En este 3er y último ejemplo, buscamos las coincidencias de una subexpresión con cada parte de la
línea, es decir el código postal (\1), la tabulación (\2) y el nombre de la ciudad (\3)

$ sed 's/\([0-9]*\)\(\t\)\(.*\)/\3\2\1/' plop
Toulouse 31000
Montpellier 34000
Perpignan 66000

Una referencia hacia atrás puede llamar a una subexpresián las veces que se desee en la cadena de
reemplazo. Retomando el último ejemplo, veamos la demostración con la repetición de la tabulación
en diversos lugares:

$ sed 's/\([0-9]*\)\(\t\)\(.*\)/\2\3\2\2\1/' plop
Toulouse 31000
Montpellier 34000
Perpignan 66000



Expresión regular precedente

Cuando encuentra una coincidencia entre una cadena y una expresión regular, Sed pone en su buffer

dicha cadena por lo que es posible referirse a esta cadena en la 1ra parte del comando de
substitución "s" (LHS) sin mencionarla literalmente. En otras palabras, un comando del tipo
's//cadena_de_reemplazo/' substituirá la ultima expresión regular encontrada por Sed con la
cadena_de_reemplazo. Para ilustrar esto, retomemos nuestro fichero con las ciudades y los códigos
postales. Vamos a buscar las líneas que contengan el patrón “Montpellier”, las otras serán borradas (d)
y substituiremos "Montpellier" por "Béziers":

$ cat plop
31000 Toulouse
34000 Montpellier
64000 Perpignan

$ sed '/Montpellier/!d; s//Béziers/' plop
34000 Béziers

Para tratar lo relacionado a las subexpresiones, referencias hacia atrás y expresión regular
precedente, el ejemplo precedente muestra otra faceta de las posibilidades que ofrece sed. Si el
patrón buscado es encerrado entre paréntesis, entonces se convierte en una subexpresión que luego
puede ser invocada en la parte derecha del comando “s”:

sed '/\(Montpellier\)/!d;s//Béziers-\1/' plop
34000 Béziers-Montpellier

$ sed '/\(Mon\)tpellier/!d;s//Béziers-\1blanc/' plop
34000 Béziers-Monblanc



La negación

A veces puede ser útil excluir una línea que coincide con un patrón (o un rango de lineas) para que no
sea procesada. Para ello, Sed utiliza el carácter "!" (signo de exclamación) que como en la mayoría de
herramientas derivadas de Unix expresa la negación, exactamente como lo hace el comando "grep -
v". Para ello, tan solo hay que poner a continuación del patrón (o el numero de línea o rango de lineas)
el carácter "!":

sed -n '3 !p' fich.txt
sed -n '3,8 !p' fich.txt
sed -n '/indice/! p' fich3.txt

A menudo encontramos en los scripts Sed, la expresión "$!" que significa “mientras no se alcance la
ultima línea” y permite efectuar uno o varios comandos mientras esta condición sea verdadera.
Podemos comparar diferentes maneras de escribir la sintaxis de un comando, pero obteniendo un
mismo resultado.

echo -e 'a\nb\n\nc\nd\ne\n\nf\ng' | sed '/./! d'
echo -e 'a\nb\n\nc\nd\ne\n\nf\ng' | sed '/^$/ d'
echo -e 'a\nb\n\nc\nd\ne\n\nf\ng' | sed -n '/^$/! p'
echo -e 'a\nb\n\nc\nd\ne\n\nf\ng' | sed -n '/./ p'



La agrupación de comandos

/dirección/{...} (acepta un rango de direcciones)

Las llaves permiten agrupar comandos que serán ejecutados en una dirección o en un rango de
direcciones. Dentro de la agrupación de estos comandos podemos encontrar otras direcciones
así como otros comandos agrupados también entre llaves.

Su principal función, indicar una línea (o rango de líneas) y aplicar sucesivamente uno o varios
comandos. El procesamiento es realizado sobre el contenido del buffer y no sobre la línea original, por
lo que las modificaciones realizadas pueden condicionar los criterios de selección posteriores.

sed '
/a/{ # solo la línea que contiene "a"
s/a/c/g # reemplazar todas las "a" por "c"
/c/{ # solo la línea que contiene "c" de la línea que coincide
s/c/A/g # reemplazar todas las "c" por "A"
}
}
' < <(echo -e "aaa\nbbb\nccc\nddd")

AAA
bbb
ccc
ddd


$ echo -e "aaa\nbbb\nccc\nd
  • Links de descarga
http://lwp-l.com/pdf9939

Comentarios de: Sed - Introducción a SED - Parte II (0)


No hay comentarios
 

Comentar...

Nombre
Correo (no se visualiza en la web)
Valoración
Comentarios
Es necesario revisar y aceptar las políticas de privacidad