Buscar y reemplazar dentro de un archivo de texto desde un comando Bash

Resuelto Ash asked hace 15 años • 18 respuestas

¿Cuál es la forma más sencilla de buscar y reemplazar una cadena de entrada determinada, por ejemplo abc, y reemplazarla con otra cadena, por ejemplo, XYZen el archivo /tmp/file.txt?

Estoy escribiendo una aplicación y usando IronPython para ejecutar comandos a través de SSH, pero no conozco muy bien Unix y no sé qué buscar.

He oído que Bash, además de ser una interfaz de línea de comandos, puede ser un lenguaje de programación muy potente. Si esto es cierto, supongo que puedes realizar acciones como estas.

¿Puedo hacerlo con Bash y cuál es el script más simple (de una línea) para lograr mi objetivo?

Ash avatar Feb 08 '09 18:02 Ash
Aceptado

La forma más sencilla es utilizar sed(o Perl):

sed -i -e 's/abc/XYZ/g' /tmp/file.txt

que invocará sedpara realizar una edición in situ debido a la -iopción. El /gindicador del comando sed's sindica reemplazar globalmente, es decir, no sustituir sólo la primera aparición en cada línea de entrada. Esto se puede llamar desde Bash.

(La -iopción no es estándar. En plataformas basadas en BSD, incluido MacOS, necesita un argumento de opción explícito -i '').

Si realmente desea utilizar solo Bash, lo siguiente puede funcionar:

while IFS='' read -r a; do
    echo "${a//abc/XYZ}"
done < /tmp/file.txt > /tmp/file.txt.t
mv /tmp/file.txt{.t,}

Esto recorre cada línea, realiza una sustitución y escribe en un archivo temporal (no quiero dañar la entrada). Al mvfinal simplemente mueve el archivo temporal al nombre original. (Por razones de solidez y seguridad, el nombre del archivo temporal no debe ser estático ni predecible, pero no vayamos a eso).

Esto utiliza una expansión de parámetro solo de Bash para realizar un reemplazo en el valor de la variable.

johnny avatar Feb 08 '2009 12:02 johnny

La manipulación de archivos normalmente no la realiza Bash, sino los programas invocados por Bash, por ejemplo:

perl -pi -e 's/abc/XYZ/g' /tmp/file.txt

La -ibandera le indica que realice un reemplazo en el lugar.

Consulte man perlrunpara obtener más detalles, incluido cómo realizar una copia de seguridad del archivo original.

Alnitak avatar Feb 08 '2009 12:02 Alnitak

Esta es una publicación antigua, pero para cualquiera que quiera usar variables, como dijo @centurian, las comillas simples significan que no se expandirá nada.

Una forma sencilla de obtener variables es realizar una concatenación de cadenas, ya que esto se hace mediante yuxtaposición en bash. Lo siguiente debería funcionar:

sed -i -e "s/$var1/$var2/g" /tmp/file.txt
zcourts avatar Dec 07 '2015 12:12 zcourts

Me sorprendí cuando me topé con esto...

Hay un replacecomando que viene con el "mysql-server"paquete, así que si lo has instalado, pruébalo:

# replace string abc to XYZ in files
replace "abc" "XYZ" -- file.txt file2.txt file3.txt

# or pipe an echo to replace
echo "abcdef" |replace "abc" "XYZ"

Consulte man replacepara obtener más información sobre esto.

rayro avatar Apr 09 '2013 15:04 rayro