En un artículo anterior, cubrí cómo manipular texto con grep
. Ahora, dirija su atención al sed
(Stream Editor), que es el más adecuado para usarse en canalizaciones (datos que provienen de una canalización). El sed
La utilidad se puede utilizar para imprimir el contenido de un archivo, sustituir una línea (o varias líneas) y luego guardar el archivo. A diferencia de grep
, sed
puede sustituir una línea o varias líneas en un archivo y realizar una in situ actualización de ese archivo.
El sed
más simple invocación al sustituir foo
para bar
es:
$ sed 's/foo/bar/' inputfile
Ejemplo:Eliminar comentarios
Mientras que grep
puede formatear la salida en la pantalla, no puede modificar un archivo en su lugar. Para hacer esto, necesitaría un editor de archivos como ed
. Desde ed
no es parte de este artículo, use sed
para lograr lo mismo que hiciste con grep
en el primer ejemplo del artículo anterior. Esta vez modifica el /etc/fstab
archivo en el lugar pasando el -i
marcar a sed
. Sin el -i
flag , solo verías lo que se habría modificado.
Se le anima a ejecutar siempre sed
sin el -i
bandera, solo para asegurarse de que el resultado que produce es el esperado. El sed
La utilidad también ofrece el -i.bak
flag, que crea un archivo de copia de seguridad antes de editarlo.
El grep
final El comando para este ejemplo fue:
$ grep -v '^#' /etc/fstab > ~/fstab_without_comment
Con sed
, tienes:
# sed -i '/^#/d' /etc/fstab
/dev/mapper/VGCRYPTO-ROOT / ext4 defaults,x-systemd.device-timeout=0 1 1
UUID=e9de0f73-ddddd-4d45-a9ba-1ffffa /boot ext4 defaults 1 2
LABEL=SSD_SWAP swap swap defaults 0 0
Ejemplo:Imprimir solo /etc/passwd
usuarios
En el grep
ejemplo, imprimió solo los nombres de usuario del /etc/passwd
archivo con lo siguiente:
$ grep -Eo '^[a-zA-Z_-]+' /etc/passwd
Puedes hacer lo mismo usando sed
de la siguiente manera:
$ sed 's/^\([a-zA-Z_-]\+\).*/\1/' /etc/passwd
En el ejemplo anterior, agrupa una coincidencia entre paréntesis ()
y luego imprima el grupo coincidente con \1
(retro-referencia), que dicta el primer grupo. Para un segundo grupo, usaría \2
, y así sucesivamente.
Ejemplo:reemplazar todos foo
con bar
En sed
, puede buscar un patrón y luego reemplazar solo la aparición que coincida con el patrón. Para reemplazar todas las apariciones en el archivo inputfile1
de foo
a bar
globalmente, ejecute:
$ sed -i '/foo/bar/g' inputfile1
Ejemplo:reemplazar una única instancia
Tome el archivo inputfile2
, que tiene los siguientes contenidos:
hello world
second line should be replaced
this line should be replaced later
Di que quieres reemplazar should
con will
, pero solo para la segunda línea. Este comando se divide de la siguiente manera:
$ sed '/second/s/should/will/' inputfile2
| | | |
| | | with this pattern
| | this pattern
| substitute
Search for the pattern "second"
Esta salida se envía a la salida estándar en lugar de reemplazar el contenido del archivo. El resultado se ve así:
$ sed '/second/s/should/will/' inputfile2
hello world
second line will be replaced
this line should be replaced later
El sed
El comando distingue entre mayúsculas y minúsculas. Lo siguiente no funcionará cuando intente reemplazar World
con there
:
$ echo "Hello World" | sed 's/world/there/'
Hello World
GNU sed
introdujo una nueva bandera, /I
, que ignora el caso y lo hará realice el reemplazo con el mismo comando:
$ echo "Hello World" | sed 's/world/there/I'
Hello there
Ejemplo:Imprimir un rango de líneas y salir
Con sed
, también puede imprimir líneas y salir una vez que se cumplan sus criterios. Los siguientes comandos imprimirán tres líneas y saldrán. Este comando:
$ sed -n '1,3p' /etc/passwd
es equivalente a:
$ sed '3q' /etc/passwd
Lo siguiente estaría mal:
$ sed '1,3q' /etc/passwd # Wrong. You cannot quit three times
Ejemplo:comentar líneas sin comentar
Las expresiones regulares también se pueden usar con sed
, como se demostró anteriormente. Por ejemplo, tiene el siguiente script pequeño:
$ cat test_script
#/usr/bin/env bash
this is the first comment
This is another comment
# this is a comment too
echo "This is not a comment and should be echoed"
Ahora debe omitir la primera línea, comenzando con #!/bin/bash
y comente las líneas tercera y cuarta, pero no la quinta porque esa línea ya está comentada.
En sed
, puede usar algo como lo siguiente:
$ sed '3,6s/^[^#]/# &/g' test_script
#/usr/bin/env bash
# this is the first comment
# This is another comment
# this is a comment too
echo "This is not a comment and should be echoed"
En el comando anterior, se realiza lo siguiente:
3,6s
define un rango, desde la línea tres hasta la línea seis./^[^#]/
coincide con todo lo que es un carácter y no comienza con un hash (#
)./# &/g
reemplaza una parte, en este caso pone un#
delante de la línea dictada por&
firmar.
Ejemplo:eliminar todos los dígitos
Diferentes aplicaciones generan datos en diferentes formatos. Con sed
, solo puede conservar los datos que puede usar. Por ejemplo, tiene el siguiente archivo (inputfile3
) en este formato:
foo1234
bar99128
baz2842
qux12953
discard39120
Tal vez un programa generó el formato incorrecto o concatenó los campos en uno. ¿Qué pasaría si solo estuviera interesado en mantener los caracteres alfabéticos y quisiera descartar los dígitos? ¿Cómo lograrías este objetivo con sed
? ?
La respuesta es probablemente más fácil de lo que piensas:
$ sed 's/\([a-z]*\).*/\1/' inputfile3
foo
bar
baz
qux
discard
Ejemplo:cambiar líneas específicas
Además, sed
también puede manejar rangos por patrón, lo que significa que puede especificar un inicio y un fin cadena y manipular el rango. Por ejemplo:
$ cat inputfile4
hello world
start of the comment
another comment
end of a comment
dont comment this line
nor this line
El siguiente sed
El comando comentará las líneas que comienzan con start y terminando en fin :
$ sed '/start/,/end/ s/^/# /' inputfile4
hello world
# start of the comment
# another comment
# end of a comment
dont comment this line
nor this line
Deshazte de las líneas vacías también.
$ sed '/start/,/end/ s/^/# /;/^$/d' inputfile4
hello world
# start of the comment
# another comment
# end of a comment
dont comment this line
nor this line
Hay mucho más para sed
y sus ricas características. Para poder utilizar completamente sed
habilidades de, consulte su página de documentación, que puede encontrar aquí. Además, una gran fuente de información sobre sed
se puede encontrar aquí.
Resumen
Como cubrí anteriormente, usará grep
cuando desee buscar un patrón, ya sea en un archivo o en varios directorios de forma recursiva. Usa sed
si está recibiendo datos de una canalización o desea manipular datos sobre la marcha.
El sed
El comando está escrito y es fácil de aprender a realizar operaciones básicas. Todo lo que necesitas es práctica, especialmente con expresiones regulares.