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
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.