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 ased
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 deSEARCH_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.