Buscar y reemplazar dentro de un archivo de texto desde un comando Bash
¿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, XYZ
en 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?
La forma más sencilla es utilizar sed
(o Perl):
sed -i -e 's/abc/XYZ/g' /tmp/file.txt
que invocará sed
para realizar una edición in situ debido a la -i
opción. El /g
indicador del comando sed
's s
indica 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 -i
opció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 mv
final 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.
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 -i
bandera le indica que realice un reemplazo en el lugar.
Consulte man perlrun
para obtener más detalles, incluido cómo realizar una copia de seguridad del archivo original.
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
Me sorprendí cuando me topé con esto...
Hay un replace
comando 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 replace
para obtener más información sobre esto.