GNU/Linux >> Tutoriales Linux >  >> Linux

Manipulación de texto en la línea de comando con sed

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.


Linux
  1. Reemplace las comillas tipográficas con el comando sed de Linux

  2. Aprende a usar el editor de texto Sed

  3. Ordenarse con ordenar en la línea de comando

  4. Trabajar con flujos de datos en la línea de comandos de Linux

  5. Multitarea en la línea de comandos con screenie

Cómo usar Nano, el editor de texto de línea de comandos de Linux

Domina la línea de comandos de Linux

Manipulación de texto con sed y grep

Manipulación de texto en la línea de comando con grep

Seguimiento del tiempo con Timewarrior en la línea de comandos

Uso del comando sed de Linux con ejemplos