Cuando trabaje con archivos de texto, a menudo necesitará buscar y reemplazar cadenas de texto en uno o más archivos.
sed
es un s tren ed itor Puede realizar manipulaciones de texto básicas en archivos y flujos de entrada, como canalizaciones. Con sed
, puede buscar, encontrar y reemplazar, insertar y eliminar palabras y líneas. Admite expresiones regulares básicas y extendidas que le permiten hacer coincidir patrones complejos.
En este artículo, hablaremos sobre cómo encontrar y reemplazar cadenas con sed
. También le mostraremos cómo realizar una búsqueda recursiva y reemplazar.
Buscar y reemplazar cadena con sed
#
Hay varias versiones de sed
, con algunas diferencias funcionales entre ellos. macOS usa la versión BSD, mientras que la mayoría de las distribuciones de Linux vienen con GNU sed
preinstalado por defecto. Usaremos la versión GNU.
La forma general de buscar y reemplazar texto usando sed
toma la siguiente forma:
sed -i 's/SEARCH_REGEX/REPLACEMENT/g' INPUTFILE
-i
- Por defecto,sed
escribe su salida en la salida estándar. Esta opción le dice ased
para editar archivos en su lugar. Si se proporciona una extensión (por ejemplo, -i.bak), se crea una copia de seguridad del archivo original.s
- El comando sustituto, probablemente el comando más usado en sed./ / /
- Carácter delimitador. Puede ser cualquier carácter, pero generalmente la barra oblicua (/
) se utiliza el carácter.SEARCH_REGEX
- Cadena normal o una expresión regular para buscar.REPLACEMENT
- La cadena de reemplazo.g
- Bandera de reemplazo global. Por defecto,sed
lee el archivo línea por línea y cambia solo la primera aparición deSEARCH_REGEX
en una línea Cuando se proporciona el indicador de reemplazo, se reemplazan todas las ocurrencias.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 cómo podemos usar el sed
Comando para buscar y reemplazar texto en archivos con algunas de sus opciones y banderas más utilizadas.
Para fines de demostración, utilizaremos el siguiente archivo:
file.txt123 Foo foo foo
foo /bin/bash Ubuntu foobar 456
Si el g
se omite el indicador, solo se reemplaza 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 foobar
string también se reemplaza en el ejemplo anterior. Si este no es el comportamiento deseado, use la expresión de límite de palabra (\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 el patrón coincida con mayúsculas y minúsculas, use el I
bandera. En el siguiente ejemplo estamos usando tanto el g
y I
banderas:
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 (/
) necesitará usar la barra invertida (\
) para escapar de la barra inclinada. Por ejemplo, para reemplazar /bin/bash
con /usr/bin/zsh
usarías
sed -i 's/\/bin\/bash/\/usr\/bin\/zsh/g' file.txt
La opción más fácil y mucho más legible es usar otro carácter delimitador. La mayoría de la gente usa la barra vertical (|
) o dos puntos (:
) pero puedes 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 la cadena number
usarías:
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 de y comercial &
que corresponde al patrón emparejado. El personaje se puede usar 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 con sed
. Para hacer eso, simplemente proporcione una extensión para el archivo de copia de seguridad en -i
opción. Por ejemplo, para editar el file.txt
y guarde el archivo original como file.txt.bak
usarías:
sed -i.bak 's/foo/linux/g' file.txt
Para asegurarse de que se crea la copia de seguridad, enumere los archivos con el ls
comando:
ls
file.txt file.txt.bak
Buscar y reemplazar recursivamente #
A veces, es posible que desee buscar directorios recursivamente en busca de 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 recursivamente en el directorio y canalizar los nombres de los archivos a sed
.
El siguiente comando buscará recursivamente archivos 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 -print0
opción, que le dice a find
para imprimir el nombre del archivo, seguido de un carácter nulo y canalizar la salida a sed
usando xargs -0
:
find . -type f -print0 | xargs -0 sed -i 's/foo/bar/g'
Para excluir un directorio, use -not -path
opción. Por ejemplo, si está reemplazando una cadena en su repositorio git local para excluir todos los archivos que comienzan con un punto (.
), usa:
find . -type f -not -path '*/\.*' -print0 | xargs -0 sed -i 's/foo/bar/g'
Si desea buscar y reemplazar texto solo en archivos con una extensión específica, utilizará:
find . -type f -name "*.md" -print0 | xargs -0 sed -i 's/foo/bar/g'
Otra opción es usar el grep
comando para buscar recursivamente todos los archivos que contienen el patrón de búsqueda y luego canalizar los nombres de archivo a sed
:
grep -rlZ 'foo' . | xargs -0 sed -i.bak 's/foo/bar/g'
Conclusión #
Aunque pueda parecer complicado y complejo, al principio, buscar y reemplazar texto en archivos con sed
es muy simple.
Para obtener más información sobre sed
comandos, opciones y banderas, visite el manual de sed de GNU y el tutorial de sed de Grymoire.
Si tiene alguna pregunta o comentario, no dude en dejar un comentario.