Cómo usar el comando Sed para buscar y reemplazar cadenas en Linux

27 feb 2021 4 min di lettura
Cómo usar el comando Sed para buscar y reemplazar cadenas en Linux
Indice dei contenuti

Introducción

Muy a menudo, cuando se trabaja con archivos de texto, es necesario buscar y reemplazar cadenas de texto en uno o más archivos.

sed es un itor s tream ed. Puede realizar manipulaciones de texto básicas en archivos y flujos de entrada como una canalización. Con sed puede buscar, buscar y reemplazar, insertar y eliminar palabras y líneas. Admite expresiones regulares básicas y extendidas que le permiten combinar patrones complejos.

En este artículo, hablaremos sobre cómo buscar y reemplazar cadenas con sed. También le mostraremos cómo realizar una búsqueda recursiva y reemplazarla.

Encontrar y reemplazar

Hay varias versiones de sed, con algunas diferencias funcionales entre ellas. macOS usa la versión BSD y la mayoría de las distribuciones de Linux vienen con GNU sed preinstalado de forma predeterminada. Usaremos la versión GNU.

La forma general de buscar y reemplazar texto usando sed tiene la siguiente forma:

sed -i 's/SEARCH_REGEX/REPLACEMENT/g' INPUTFILE
  • -i: por defecto, sed escribe la salida en la salida estándar. Esta opción le dice a sed que modifique los archivos en curso. Si se proporciona una extensión (ex -i.bak), se creará una copia de seguridad del archivo original.
  • s: el comando de reemplazo, probablemente el comando más utilizado en sed.
  • /// - Carácter delimitador. Puede ser cualquier carácter, pero normalmente se utiliza /
  • SEARCH_REGEX: cadena normal o expresión regular para buscar.
  • REPLACEMENT - La cadena de reemplazo.
  • g - Bandera de reemplazo global. De forma predeterminada, sed lee el archivo línea por línea y cambia solo la primera aparición de SEARCH_REGEX en una línea. Cuando se da la bandera de reemplazo, todas las ocurrencias serán reemplazadas.
  • INPUTFILE: el nombre del archivo en el que desea ejecutar el comando.

Es una buena práctica poner comillas alrededor del argumento para que los metacaracteres del shell no se expandan.

Veamos ejemplos de cómo usar el sed para buscar y reemplazar texto en archivos con algunas de sus opciones y banderas más utilizadas.

Para fines de demostración, usaremos el siguiente archivo.txt:

123 Foo foo foo
 foo /bin/bash Ubuntu foobar 456

Si omite el g, solo se reemplazará la primera instancia de la cadena de búsqueda en cada línea:

sed -i 's/foo/linux/' file.txt
123 Foo linux foo
 linux /bin/bash Ubuntu foobar 456

Con la bandera de reemplazo global, sed reemplaza todas las apariciones del patrón de búsqueda:

sed -i 's/foo/linux/g' file.txt
123 Foo linux linux
 linux /bin/bash Ubuntu linuxbar 456

Como habrás notado, la subcadena foo dentro de la cadena foobar también se reemplazó en el ejemplo anterior. Si este no es el comportamiento deseado, use la expresión word-boundery ( \b ) en ambos extremos de la cadena de búsqueda. Esto asegura que las palabras parciales no coincidan.

sed -i 's/\bfoo\b/linux/g' file.txt
123 Foo linux linux
 linux /bin/bash Ubuntu foobar 456

Para hacer que la coincidencia de patrones sea insensible, use la bandera I En el siguiente ejemplo, estamos usando tanto la g como la bandera I

sed -i 's/foo/linux/gI' file.txt
123 linux linux linux
 linux /bin/bash Ubuntu linuxbar 456

Si desea buscar y reemplazar una cadena que contiene el carácter delimitador ( / ), deberá usar la barra invertida ( \ ) para escapar de la barra diagonal. Por ejemplo, para reemplazar /bin/bash con /usr/bin/zsh usaría

sed -i 's/\/bin\/bash/\/usr\/bin\/zsh/g' file.txt

La opción más simple y mucho más legible es usar otro carácter delimitador. Mucha gente usa la tubería | o dos puntos : pero puede usar cualquier otro carácter:

sed -i 's|/bin/bash|/usr/bin/zsh|g' file.txt
123 Foo foo foo
 foo /usr/bin/zsh Ubuntu foobar 456

También puede utilizar expresiones regulares. Por ejemplo, para buscar todos los números de 3 dígitos y reemplazarlos con el number cadena que usaría:

sed -i 's/\b[0-9]\{3\}\b/number/g' file.txt
number Foo foo foo
 foo /bin/bash demo foobar number

Otra característica útil de sed es que puede usar el carácter ampersand & que coincide con el patrón coincidente. El personaje se puede utilizar varias veces.

Por ejemplo, si desea agregar llaves {} alrededor de cada número de 3 dígitos, escriba:

sed -i 's/\b[0-9]\{3\}\b/{&}/g' file.txt
{123} Foo foo foo
 foo /bin/bash demo foobar {456}

Por último, pero no menos importante, siempre es una buena idea hacer una copia de seguridad al editar un archivo sed Para hacer esto, simplemente proporcione una extensión para la opción -i Por ejemplo, para editar file.txt y guardar el archivo original como file.txt.bak use:

sed -i.bak 's/foo/linux/g' file.txt

Si desea asegurarse de que se creó la copia de seguridad, enumere los archivos con el comando ls

ls
file.txt file.txt.bak

Buscar y reemplazar recursivo

A veces, desea buscar en directorios de forma recursiva archivos que contengan una cadena y reemplazar la cadena en todos los archivos. Esto se puede hacer usando comandos como find o grep para buscar archivos de forma recursiva en el directorio y redirigir los nombres de los archivos sed

El siguiente comando buscará archivos de forma recursiva en el directorio de trabajo actual y pasará los nombres de archivo a sed.

find. -type f -exec sed -i 's/foo/bar/g' {} +

Para evitar problemas con archivos que contienen espacios en sus nombres, use la -print0 que le dice al find que imprima el nombre del archivo, seguido de un carácter nulo y redirija la salida a sed usando xargs -0:

find. -type f -print0 | xargs -0 sed -i 's/foo/bar/g'

Para excluir un directorio, use la opción -not -path Por ejemplo, si está reemplazando una cadena en su repositorio local de git para excluir todos los archivos que comienzan con un punto ( . ), Use:

find. -type f -not -path '*/\.*' -print0 | xargs -0 sed -i 's/foo/bar/g'

Si desea buscar y reemplazar texto solo en una extensión de archivo específica, use:

find. -type f -name "*.md" -print0 | xargs -0 sed -i 's/foo/bar/g'

Otra opción es usar el grep para buscar recursivamente todos los archivos que contienen el patrón de búsqueda y luego redirigir los nombres de archivo a sed:

grep -rlZ 'foo'. | xargs -0 sed -i.bak 's/foo/bar/g'

Conclusión

Para obtener más información sobre los sed comandos, opciones y banderas, visite la sed de GNU Manual.

Buy me a coffeeBuy me a coffee

Supportaci se ti piacciono i nostri contenuti. Grazie.

Successivamente, completa il checkout per l'accesso completo a Noviello.it.
Bentornato! Accesso eseguito correttamente.
Ti sei abbonato con successo a Noviello.it.
Successo! Il tuo account è completamente attivato, ora hai accesso a tutti i contenuti.
Operazione riuscita. Le tue informazioni di fatturazione sono state aggiornate.
La tua fatturazione non è stata aggiornata.