Ejecuté lo siguiente para reemplazar un término utilizado en todos los archivos en el directorio de trabajo actual:
$ find . -type f -print0 | xargs -0 sed -i'.bup' -e's/Ms. Johnson/Mrs. Melbin/g'
Esto realizó la sustitución de palabras pero también creó .bup
archivos de archivos que nunca tuvieron la Ms. Johnson
cadena.
¿Cómo realizo la sustitución sin crear todas estas copias de seguridad innecesarias?
linux
shell-script
scripting
sed
Belmin Fernandez
fuente
fuente
ex
y ejecutando condicionalmente (solo si se cambia el archivo):!cp '%' '%.bup'
antes de guardar y salir. Puede que valga la pena mirar más a fondo.vi
intercambio de pila.Respuestas:
Puede verificar el contenido de los archivos para asegurarse de que se realizará una sustitución cuando los
sed
opere:Si quieres ser realmente inteligente al respecto, puedes renunciar a usar
find
:fuente
'{}'
poco antes\;
de eso-exec
.Find tiene un
-exec
operador que ejecuta un comando arbitrario. Aún mejor,-exec
es un prueba , por lo que puede encadenar varios-exec
s juntos, y si los comandos anteriores fallan, los posteriores no se ejecutarán. La cadena{}
se reemplaza con el nombre de archivo actual y;
marca el final del comando. Debe citar ambos para evitar la interferencia del shell.Entonces:
fuente
{}
a la cadena nula cuando se hace la expansión de llaves.Miré la página de manual y no vi ninguna forma de hacerlo directamente
sed
, como estoy seguro de que lo hiciste antes de preguntar. Veo varias formas de evitar esto usando grep, pero creo que la más fácil es esta:-r
-l
nombre de archivo de impresión recurse solo-Z
nombres finales con nulofuente
Parece que primero debe crear una lista de archivos que coincidan con sus términos de búsqueda.
fuente
.
como el primer argumento parafind
. Además, como me informaron hace poco, en realidad no es necesario citar o escapar del{}
find
genera una lista de archivos separados por una nueva línea, luego el shell divide esta lista en cualquier espacio en blanco (no solo en las nuevas líneas) y luego el shell trata cada palabra como un patrón global. Esto solo funciona si sus nombres de archivo no contienen espacios en blanco o\[?*
. Otras respuestas en esta página muestran cómo hacer esto correctamente..
es innecesario con find (al menos find found en linux) porque se asume cuando no se pasa una ruta a un argumento.