Notxor tiene un blog

Defenestrando la vida


Utilizando Dired para reemplazar cadenas en varios ficheros

Hasta ahora, le había echado pocas cuentas a dired. Es un paquete de emacs que se utiliza para trabajar con los ficheros del disco. Sin embargo, estoy acostumbrado a hacerlo casi todo desde la línea de comandos. Si necesito algo más visual en modo gráfico utilizo el Dolphin de KDE-plasma y en modo texto utilizo el incombustible mc.

El caso es que estaba trabajando en una traducción que implica varios ficheros y son bastantes. En el texto, había dejado sin traducir el nombre de un lugar y su gentilicio, porque pensaba que no había traducción y a medio proyecto, encontré que sí... ¿Cambiar ahora todo lo que ya está traducido en varios ficheros? ¿Uno a uno? ¿No hay un medio más rápido? Pues sí, en emacs lo hay: una breve búsqueda por Internet y un poco de buceo por la ayuda me dijo cómo. Así, vengo aquí a contarlo para que no se me olvide.

Dired y sus cosas

Alguna vez he contado ya que utilizo dired-sidebar cuando trabajo en proyectos que implican varios ficheros porque me permite abrirlos con un par de clicks, borrar ficheros secundarios que se generan al convertir de LaTeX a pdf, etc. Sin embargo, esta vez necesitaba otras cosas que no suelo utilizar. Por ejemplo, seleccionar algunos ficheros y otros no. El método habitual de selección que utilizo es la combinación de teclas % m poniendo luego la extensión de los ficheros con los que quiero trabajar, por ejemplo: .org. Si quiero desmarcar alguno, me sitúo en él y pulso u (o U si quiero desmarcarlos todos). Si quiero marcar alguno más, me pongo sobre él y pulso m. Cuando los tengo todos marcados realizo sobre ellos la acción que quiero realizar. Hasta ahora no me había fijado en que la opción Q realiza la acción dired-do-find-regexp-and-replace, que como su nombre indica buscará una expresión a lo largo de los ficheros marcados en dired y la reemplazará con otra. Básicamente, lo mismo que hace la función query-replace-regexp en un fichero, lo repite en todos ellos.

Una vez que hemos pulsado Q en el buffer de dired, nos pregunta por las expresiones que queremos utilizar: la primera será la que buscará en los ficheros seleccionados y la segunda su reemplazo. Las combinaciones de teclas que podemos utilizar son muy similares a las de query-replace: y para que reemplace la cadena, n para que la salte, ! para que reemplace todas sin preguntar más en el fichero actual. Además, se añaden alguna tecla más: N deja de reemplazar en el fichero actual y pasa al siguiente y Y lo hace en todos los ficheros sin volver a preguntar más.

Como no hice capturas de pantalla mientras hacía el trabajo para utilizarlas luego en este artículo (cuando lo hice tampoco pensé en escribirlo en el blog). He hecho una captura con un búsqueda en los ficheros del blog para sustituir elisp por emacs lisp. No voy a sustituir nada, pero me servirá para explicar algunas cosas más.

Trabajando en el reemplazo

captura-pantalla-dired-replace.png

Como se puede apreciar en la captura, se abren un par de buffers para realizar la sustitución. Hay uno llamado *xref* que es básicamente un listado de ficheros en los que se ha encontrado la expresión buscada, junto con las líneas en las que se encuentran.

Ese buffer nos sirve para reanudar el trabajo de sustitución ─en caso de que lo perdamos─, pulsando r y nos preguntará de nuevo por las expresiones a buscar. También podemos movernos por sus líneas con n y p. Eso nos irá llevando en otro buffer a la posición marcada del fichero.

Guardando lo cambiado

Una vez hechas las modificaciones hay que guardarlas. Si se han modificado dos o tres ficheros, no hay problema por darle un par de veces a la y para guardar cuando cerramos, pero si son muchos los ficheros modificados, también puede hacerse tediosa esa operación. ¿Alguna sugerencia? Pues sí: ibuffer. El comando ibuffer trabaja con los buffers de modo similar a como dired trabaja con ficheros del disco.

En ese caso si después de llamar a M-x ibuffer pulsamos S guardará los cambios en los buffers abiertos que se hayan modificado y posteriormente podemos cerrarlos con D. El modo ibuffer es parecido a la lista de buffers que se obtiene con C-x C-b, aunque cambian las opciones que puedes realizar a golpe de tecla.


Comentarios