¿Requieres de una instalación o configuración de Linux o sus servicios?
¿Un desarrollo WEB empresarial a la medida?
¿Un curso o capacitación a la medida?
Revisa el sitio de SERVICIOS de LinuxTotal


Uso básico de SED para
manipular texto en Linux 

Copyright © 2005-2024 LinuxTotal.com.mx
Se concede permiso para copiar, distribuir y/o modificar este documento siempre y cuando se cite al autor y la fuente de linuxtotal.com.mx y según los términos de la GNU Free Documentation License, Versión 1.2 o cualquiera posterior publicada por la Free Software Foundation.


Traducción y adaptación por: sergio.gonzalez.duran@gmail.com

Artículo original en inglés: The Basics of Using the Sed Stream Editor to Manipulate Text in Linux por: Justin Ellingwood


Introducción

El editor en línea (stream editor) sed es un editor de texto en línea que realiza operaciones de edición sobre datos provenientes desde un archivo o desde el "standard input" (Entrada de datos estandar mejor conocido como teclado). sed edita línea por línea en un modo no interactivo.

Esto quiere decir que tu realizas todas las decisiones de edición conforme se ejecuta el comando y sed ejecuta las directivas automáticamente. Esto resulta confuso o poco intuitivo, pero es un modo muy poderoso y un método rápido para transforma text.

Este tutorial de sed tratará sobre operaciones básicas y te presentará la sintaxis requerida para operar este editor. Ciertamente nunca reemplazarás tu editor de texto regular (como vim) con sed, pero muy probabblemente, una vez que aprendas su facilidad de uso, será una addición bienvenida a tus herramientas de edición de texto.


Uso básico

De maneral general, sed opera sobre un flujo de texto que es leido desde un archivo o desde "standard input". Esto quiere decir que se puede enviar la salida de un comando directamente a sed para ser editado o tu puedes indicar un archivo que ya este previamente creado.

Por otro lado, el resultado o salida de sed es enviado por default a la pantalla. O si es redireccionado será enviado a la archivo que indiques.

Modos básicos es:

$ sed [opciones] comandos [archivo_a_editar]
$ sed [opciones] comandos archivo > archivo_de_salida    
$ otro_comado | sed [opciones] comandos
$ otro_comado | sed [opciones] comandos > archivo_de_salida

Para practicar lo anterior, copiemos algunos archivos en nuestro directorio HOME para practicar con sed.

cd
cp /usr/share/common-licenses/BSD .
cp /usr/share/common-licenses/GPL-3 .

Ya que sabemos que sed envia su resultado a la pantalla por default, podemos usarlo como un visor (o lector) de archivos al no pasarle "comandos" de edición, veamos:

$ sed '' BSD

Copyright (c) The Regents of the University of California.
All rights reserved.

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the above copyright
   notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
   notice, this list of conditions and the following disclaimer in the
   documentation and/or other materials provided with the distribution.
...
...

Esto funciona porque enntre las comillas simples se indican los comandos de edición que se le pasan a sed. Al no pasarle o innicarle nada entonces tan solo imprime cada línea que recibe a la pantalla (standard output).

Veamos como sed puede usar el "standard input" al canalizar (piping) la salida del comando cat hacía sed para producir el mismo resultado mostrado anteriormente:

$ cat BSD | sed ''

Copyright (c) The Regents of the University of California.
All rights reserved.

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the above copyright
   notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
   notice, this list of conditions and the following disclaimer in the
   documentation and/or other materials provided with the distribution.
...
...

Como se puede ver, podemos trabajar igual de fácil con archivos o con flujos de texto , como el que se produce cuando canalizamos la salida de cat con "|" pipe.


Imprimiendo líneas

En el ejemplo previo, vimos como al pasar un archivo o flujo de texto al comando sed sin ningún comando, imprime el resultado directamente a la pantalla (standard output).

El primer comando que aprenderemos será el comando p dentro de las comillas sencillas:

$ sed 'p' BSD

Copyright (c) The Regents of the University of California.
Copyright (c) The Regents of the University of California.
All rights reserved.
All rights reserved.


Redistribution and use in source and binary forms, with or without
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
modification, are permitted provided that the following conditions
...
...

Se puede observar que sed imprimió cada línea dos veces. Esto es porque de manera automática sed ya imprime cada línea, y entonces al añadir el comando p le estamos diciendo que imprima explícitamente cada línea.

Este ejemplo es importante para entender como trabaja sed. Si se examina como la salida tiene la primera línea dos veces, y después la segunda línea igual, dos veces, etc. se entenderá entonces que sed opera siempre línea por línea. Es decir, acepta una línea, opera en ella con el o los comandos indicados y después muestra el texto resultante en la salida antes de operar con la siguiente línea.

Podemos limpiar el resultado al indicar la opción -n que suprime la impresión automática de líneas.

$ sed -n 'p' BSD

Copyright (c) The Regents of the University of California.
All rights reserved.

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
...
...

Ahora solo vemos la impresión de solo una línea a la vez.

Este último ejemplo también muestra un ejemplo de sed completo:

$ sed -n 'p' BSD
$ sed [opciones] comandos archivo_de_texto

Rangos (address ranges)

Los ejemplos mostrados hasta ahora no pueden ser considerados de edición (solo que la intención sea explícitamente imprimir cada renglón dos veces). Modificquemos ahora la salida indicándole a sed que solo deseamos imrimir la prímera línea.

$ sed -n '1p' BSD
Copyright (c) The Regents of the University of California.

Al colocar el número "1" antes del comando imprimir p (print), le estamos indicando a sed explícitamente sobre que línea operar. Si queremos operar sobre un rango de líneas maor, por ejemplo las primeras 5 líneas, podemos fácilmente indicarlo de la siguiente manera (no olvides la opción -n) :

$ sed -n '1,5p' BSD
Copyright (c) The Regents of the University of California.
All rights reserved.

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions

Le hemos indicado a sed un rango de direcciones (address range), o mas entendible, un rango de renglones sobre los cuales operar. Al indicar un rango, solo se ejecutaran los comandos en esas líneas específicas del rango. en este último ejemplo de la línea 1 a la 5.

Otro modo de lograr exactamente el mismo resultado es indicando el renglón o rango inicial y entonces indicar un número de desplazamiento (offset) para indicarle a sed cuantas líneas adicionales utilizar.

$  sed -n '1,+4p' BSD
 
$ sed -n '1,5p' BSD

Rangos cada X línea

Si lo que deseas es imprimir cada otra línea, o cada 2 líneas, se indica el caracter ~ (tilde) para esto. seguido del número de cada x líneas imprimir, veamos con ejemplos:

$ sed -n '1~2p' archivo_de_texto    
$ sed -n '7~3p' archivo_de_texto    

Eliminando texto

Se puede fácilmente realizar operaciones de borrado o eliminación de texto tan solo cambiando el comando p por el comando d (delete, borrar en inglés).

Cuando se trabaja con el comando d ya no es necesario indicar la opción -n porque al utilizar el comando "delete" sed mostrará en pantalla (por default) todo lo que NO ha sido eliminado, que ayuda a darse cuenta que esta sucediendo.

Podemos modificar uno de los últimos ejemplos de la sección anterior para que elimine cada otra línea empezando por la primera. El resultado es que nos debe mostrar las líneas que NO fueran dadas con el comando p:

$ sed '1~2d' BSD

ll rights reserved.
Redistribution and use in source and binary forms, with or without
are met:
   notice, this list of conditions and the following disclaimer.
   notice, this list of conditions and the following disclaimer in the
3. Neither the name of the University nor the names of its contributors
   without specific prior written permission.
...
...


$ sed '4d' BSD
(Elimina la línea 4, pero resultado en pantalla es que se mostrará las líneas 1 a 3 y de la 5 en delante)

En los dos ejemplos previos, es muy IMPORTANTE hacer notar que el archivo original no esta siendo afectado en lo absoluto, continua intacto, nada se eliminó en el original. Las ediciones o eliminaciones de línea en este caso, son el resultado enviado a pantalla

Antes de ver como funciona la opción -i recrodemos que es muy fácil guardar tus ediciones con sed redirigiendo la salida estandar (standard output) a un archivo.

$ sed '1~2d' BSD > everyother.txt 

Si abrimos este archivo con cat o more veremos la misma salida que vimos en la pantalla previamente. Por nuestra seguridad sed no edita el documento fuente, como ya se mencionó.

Se puede cambiar este comportamiento indicando la opción -i (in-place), que efectivamente editará el documento de texto fuente u original.

Editemos el archivo "everyother.txt" que acabamos de crear con la opción in-place -i, reduciendo el archivo al eliminar cada otra línea de nuevo.

$ sed -i '1~2d' everyother.txt

Si usamos cat de nuevo, podrás ver que el archivo fue efectivamente editado.

El uso de la opción -i puede ser peligrosa. Afortunadamente, sed nos da la opción de crear un respaldo del archivo antes de editar el mismo.

$ sed -i.bkp '1~2d' everyother.txt

Esto creará un archivo de respaldo (backup) con la extensión ".bkp" y solo después editará el archivo indicado. Por supuesto que puedes indicar lo que gustes como extensión.


Sustitución de texto

Quizás el uso más conocido de sed es la sustitución de texto. sed tiene la habilidad de buscar por patrones de texto usando expresiones regulares y sustituir o reemplazar el text encontrado.

En su forma más simple, es posible sustituir una palabra por otra usando la siguiente sintaxis:

's/una_palabra/otra_palabra/'



's/buscar_un_patrón/sustituir_por_otro_patrón/'

s es el comando que indica "sustituir" o reemplazar. Las 3 diagonales / son usadas para separas los distintos campos. Es posible cualquier otro caracter para delimitar los campos (el que siga del comando s) si eso es más conveniente según el caso.

Por ejemplo, si estamos cambiando el nombre de un ditio web, entonces utilizar otro delimitador será más conveniente ya que los URLs contienen diagonales. En este ejemplo utilizaremos _ en vez de / como delimitador. Y también usaremos el comando echo para canalizar | (pipe) su salida a sed

$ echo "http://www.example.com/index.html" | sed 's_com/index_org/home_'

http://www.example.org/home.html

No hay que olvidar el último delimitador o sed se quejará:

$ echo "http://www.example.com/index.html" | sed 's_com/index_org/home'

sed: -e expression #1, char 22: unterminated `s' command

Vamos a crear un archivo donde podamos practicar sustituciones:

echo "this is the song that never ends
yes, it goes on and on, my friend
some people started singing it
not knowing what it was
and they'll continue singing it forever
just because..." > annoying.txt

Sustituyamos la expresión "on" por "forward".

$ sed 's/on/forward/' annoying.txt
this is the sforwardg that never ends          
yes, it goes forward and on, my friend         
some people started singing it
not knowing what it was
and they'll cforwardtinue singing it forever   
just because...

Podemos observar algunas cosas notables con este ejemplo. Primero, estamos reemplazando patrones no palabras, esto se aprecia en el tercer cambio, el "on" dentro de "song" fue cambiado a "forward".

La otra cosa a notar es que en el cambio 2, el segundo "on" no fue sustituido por "forward".

Esto es porque por defecto, el comando s opera solo en la primera ocurrencia de cada línea y entonces pasa a la siguiente línea.

Para lograr que sed reemplace cada instancia de "on" en vez de solo la primera ocurrencia, podemos entonces indicar una bandera o flag opcional al comando de sustitución s.

Indicaremos entonces para esto la bandera g (de global) al comanndo s al colocarlo después del conjunto de sustituciones:

$ sed 's/on/forward/g' annoying.txt

this is the sforwardg that never ends          
yes, it goes forward and forward, my friend    
some people started singing it                
not knowing what it was                       
and they'll cforwardtinue singing it forever   
just because...

Ahora el comando sustitución s ha cambiado cada instancia.

Si solo quisieramos cambiar la segunda instancia de "on" que sed encuentre para cada línea, usaremos entonces el número 2 como bandera en vez de la bandera g.

$ sed 's/on/forward/2' annoying.txt

this is the song that never ends
yes, it goes on and forward, my friend   
some people started singing it
not knowing what it was
and they'll continue singing it forever
just because...

Para ebitar toda la salida y solo ver las líneas donde hubo reemplazos, podemos usar la opción -n de nuevo para suprimir la impresión automática y además añadimos la bandera p (de Printing) para imprimir las líneas donde la sustitución se realizó.

$  sed -n 's/on/forward/2p' annoying.text

yes, it goes on and forward, my friend

Como se puede observar, es posible combinar banderas o flags al final del comando.

sed por defecto es sensible a mayúsculas y minúsculas. Si queremos que en el proceso de búsqueda de patrones se ignore esto, entonces podemos utilizar la bandera o flag i (de ignorar) que hace aso omiso en la búsqueda de mayúsculas y minúsculas.

$  sed 's/SINGING/saying/i' annoying.txt

this is the song that never ends
yes, it goes on and on, my friend
some people started saying it          
not knowing what it was
and they'll continue saying it forever
just because...

Si lo que se desea es encontrar patrones (patterns) complejos con expresiones regulares, tenemos diferentes métodos de referenciar el patrón encontrado o igualado en el texto de reemplazo.

Por ejemplo, si queremos igualar desde el principio de la línea hasta el patrón "at", podemos usar la expresión:

$ sed 's/^.*at/REPLACED/' annoying.txt

REPLACED never ends                   
yes, it goes on and on, my friend
some people started singing it
REPLACED it was                       
and they'll continue singing it forever
just because...

/^.*at/ recuérdese que esta parte indica el patrón a buscar. ^ indica inicio o principio de línea. . indica cualquier tipo de caracter alfanumérico, espacios, símbolos. * indica cualquier número de caracteres (o ninguno) del símbolo que precede, en este caso .* quiere decir cualquier cantidad de caracteres. En español: ^.*at encuentra cualquier cadena de caracteres desde el inicio de línea hasta donde encuentre un "at".

Ya que no sabemos la frase exacta que será encontrada en la cadena de búsqueda, se puede utilizar el caracter & que representa el texto encontrado en la parte de reemplazo.

El siguiente ejemplo muestra como poner paréntesis alrededor del texto encontrado.

$ sed 's/^.*at/(&)/' annoying.txt

(this is the song that) never ends        
yes, it goes on and on, my friend
some people started singing it
(not knowing what) it was                 
just because...

Un modo más flexible de referenciar el texto encontrado es usar paréntesis con escape \ para agrupar en secciones el texto encontrado.

Cada grupo de texto de búsqueda marcado con paréntesis puede ser referenciado por un número de referencia escapado. Por ejemplo, el primer grupo de paréntesis puede ser referenciado por \1, el segundo por \2, etcetera.

En este ejemplo, cambiaremos de orden las dos primeras palabras de cada línea.

$ sed 's/\([a-zA-Z0-9][a-zA-Z0-9]*\) \([a-zA-Z0-9][a-zA-Z0-9]*\)/\2 \1/' annoying.txt

is this the song that never ends          
yes, goes it on and on, my friend         
people some started singing it            
knowing not what it was                   
they and'll continue singing it forever   
because just...                           

Como se puede notar, los resultados no son perfectos, la 2 y 5 línea no cumplieron con lo que se pedía, debido a la , y el ' que no están indicados en nuestro conjunto de caracteres indicados.

Antes de continuar y mejorar este último ejemplo, entendamos bien el ejemplo actual:

Recordemos que el comando s se forma de la siguiente manera:

's/buscar_un_patrón/sustituir_por_otro_patrón/'

Entonces tenemos:
's/\([a-zA-Z0-9][a-zA-Z0-9]*\) \([a-zA-Z0-9][a-zA-Z0-9]*\)/\2 \1/' \([a-zA-Z0-9][a-zA-Z0-9]*\) \([a-zA-Z0-9][a-zA-Z0-9]*\) \([a-zA-Z0-9][a-zA-Z0-9]*\) = \1 \([a-zA-Z0-9][a-zA-Z0-9]*\) = \2 \2 \1

Analizemos ahora la expresión regular: \([a-zA-Z0-9][a-zA-Z0-9]*\)

\(            ah ok, ahorita no puedes
[a-zA-Z0-9] 


¿Requieres de una instalación o configuración de Linux o sus servicios?
¿Un desarrollo WEB empresarial a la medida?
¿Un curso o capacitación a la medida?
Revisa el sitio de SERVICIOS de LinuxTotal

LinuxTotal en:

Si encuentras útil la información que proveé LinuxTotal, considera realizar un donativo que estimule a seguir proporcionando contenido de calidad y utilidad. Gracias.


Dona a través de paypal::


O a través de bitcoins:


14TNQv5wM3xkSv65gHGQ6s6f8yTZuFTohE
Más artículos de LinuxTotal

Una buena contraseña o password, todos lo sabemos, es esencial para dificultar la entrada a nuestro sistema, sobre todo si se es ....


Imaginémonos a la empresa "Pato, S.A." que ofrece a sus empleados y clientes el sitio http://www.pato.com/consulta, donde mediant....


Este es un pequeño y útil tip que te permitirá crear PDF's a partir de páginas del manual. Cuando deseas ver la ayuda de un co....


Uno de mis clientes tiene múltiples aplicaciones basadas en VisualBasic 6 y como base de datos Access, que se ejecutan directamen....


Administración básica de redes. Conoce distintos métodos y herramientas para escanear, probar o buscar por puertos abiertos des....


La gente considera encriptar algunos o todos sus archivos por múltiples razones. Ya sea que no puedan depender en seguridad físi....


Sistemas basados en GNU/Linux (Al igual que sus parientes basados en Unix como BSD o los de Macinstosh) conservan la tradición de....


Aqui, traté de enviar un archivo ejecutable (notepad.exe) a través de gmail, y sus mecanismos de seguridad me lo impidieron. Gma....


En el artículo de LinuxTotal.com.mx sobre permisos se explica lo que es un archivo con permisos SUID o SGID, pueden ser potencial....


En este archivo de configuración se indica el modo en que los mensajes del sistema son bitacorizados a través de la utileria sys....



Copyright © LinuxTotal.com.mx 2006-2024
info@linuxtotal.com.mx · linuxtotal.com.mx@gmail.com