Notxor tiene un blog

Defenestrando la vida


Buscando cadenas de texto en emacs con grep

Cuando un proyecto se expande y comienza a crecer, como este blog, es complicado encontrar dónde hablaste sobre algo. Los sistemas Unix, de los que GNU/Linux es un heredero directo, proveen la herramienta grep que permite buscar texto dentro de un fichero, o de varios.

grep desde línea de comandos.

Al principio, utilizaba grep desde línea de comandos. Muchas veces, lo único que necesitaba era saber cuántas veces aparece un término o una expresión en una serie de ficheros. Si necesito buscar cuántas veces aparece el término emacs en los artículos del blog puedo lanzar el comando

grep -c "emacs" ~/proyectos/blog-org-page/blog/*

El resultado que muestra será similar a

~/proyectos/blog-org-page/blog/avances-isla-godot.org:0
~/proyectos/blog-org-page/blog/calculadora-guile.org:0
~/proyectos/blog-org-page/blog/cambios-en-mi-prompt.org:1
~/proyectos/blog-org-page/blog/cifrado-con-emacs.org:13
~/proyectos/blog-org-page/blog/codigo-minimult-por-pantalla.org:2
~/proyectos/blog-org-page/blog/como-uso-git-2.org:4
~/proyectos/blog-org-page/blog/como-uso-git.org:0
~/proyectos/blog-org-page/blog/comparacion-schemes.org:0
~/proyectos/blog-org-page/blog/compilar-chicken-android.org:1
~/proyectos/blog-org-page/blog/crei-terminar-minimult.org:6
~/proyectos/blog-org-page/blog/ejercicio-scheme.org:2
~/proyectos/blog-org-page/blog/emacs-client.org:36
~/proyectos/blog-org-page/blog/emacs-grep.org:5
~/proyectos/blog-org-page/blog/en-que-ando-2018.org:2
~/proyectos/blog-org-page/blog/entrevista-radio.org:0
~/proyectos/blog-org-page/blog/escalas-plantillas.org:2
~/proyectos/blog-org-page/blog/escribir-en-emacs.org:13
~/proyectos/blog-org-page/blog/feeds-elfeed-emacs.org:12
~/proyectos/blog-org-page/blog/hablar-de-suicidio.org:0
~/proyectos/blog-org-page/blog/importar-fichero-entre-ramas.org:2
~/proyectos/blog-org-page/blog/inicio-nuevo-blog.org:8
~/proyectos/blog-org-page/blog/me-gusta.org:0
~/proyectos/blog-org-page/blog/minimult-2.org:3
~/proyectos/blog-org-page/blog/minimult-corregido.org:2
~/proyectos/blog-org-page/blog/minimult-perfil-grafico.org:2
~/proyectos/blog-org-page/blog/mmpi.org:3
~/proyectos/blog-org-page/blog/orgzly.org:4
~/proyectos/blog-org-page/blog/otro-avance.org:1
~/proyectos/blog-org-page/blog/pasar-minimult-por-pantalla.org:3
~/proyectos/blog-org-page/blog/plantuml.org:2
~/proyectos/blog-org-page/blog/plataformas-enganosas.org:0
~/proyectos/blog-org-page/blog/quiza.org:0
~/proyectos/blog-org-page/blog/servidor-local.org:4
~/proyectos/blog-org-page/blog/simplificaciones.org:0
~/proyectos/blog-org-page/blog/tablas-org-mode.org:4
~/proyectos/blog-org-page/blog/toki-pona.org:0
~/proyectos/blog-org-page/blog/utilizando-emacs-para-otras-cosas.org:3
~/proyectos/blog-org-page/blog/viaje-a-ciria.org:0
~/proyectos/blog-org-page/blog/video-isla.org:0

Como se puede apreciar toma todos los ficheros que le hemos pasado en el directorio. En algunos resultados muestra 0 y en otras aparece el número de veces que la cadena (o expresión regular) que debe buscar. Si nos fijamos en el listado devuelto los nombres de los ficheros aparecen ordenados alfabéticamente, aunque puede ser que esa ordenación sea circunstancial y sería mejor, si lo queremos ordenado, utilizar el comando sort, o por ejemplo si quisiéramos ordenarlo en el orden contrario:

grep -c "emacs" ~/proyectos/blog-org-page/blog/* | sort -r

Pero la mayor parte de las veces necesito saber, no cuántas veces aparece, sino dónde. Normalmente busco qué los ficheros que contienen el término buscado y luego para ponerle contexto, miro en el fichero concreto que necesito. Por ejemplo:

grep -n "emacs" ~/proyectos/blog-org-page/blog/tablas-org-mode.org
6:#+KEYWORDS:    emacs
7:#+TAGS:        emacs
74:Normalmente, el ancho de columna lo calcula directamente /emacs/, pero
230:esté soportada por el modo ~calc~ de emacs. En este caso ~sqrt~ para

Como se puede ver, el parámetro -n nos dice qué línea contiene la cadena buscada.

Uso del comando grep de emacs

Hasta hace poco las búsquedas las hacía desde una consola y luego abría el archivo con emacs para ir hasta las líneas que quería modificar o consultar con el comando goto-line. Una pérdida de tiempo teniendo la posibilidad de hacer la búsqueda desde el propio editor, que abre un buffer que permite saltar directamente al sitio apropiado.

Por ejemplo, para hacer la consulta del primer ejemplo de este artículo sólo tenemos que seguir los siguientes pasos:

  1. Utilizar el comando M-x grep y pulsar <RET>.
  2. Introducir las opciones que queramos de grep, el editor sugiere el comando grep --color -nH --null -e para que añadamos la expresión que debemos buscar. La opción --color creo que no hace falta explicarla; -nH hace que se muestren los números de línea junto con el nombre del fichero; --null hace que la salida sea clara incluso si los nombres de fichero llevan caracteres extraños como saltos de línea, por ejemplo; y por último -e pide un patrón que buscar. Yo voy a añadir un nombre de fichero, el que estoy utilizando ahora. Quedaría la línea como sigue:

    grep --color -nH --null -e emacs ./emacs-grep.org

  3. Si necesito buscar el término en una serie de archivos, el PATH puede ser cualquier cadena de búsqueda habitual, por ejemplo podríamos utilizar ./*.org/ para que busque el patrón determinado por -e emacs en todos los ficheros org.
  4. Cuando aparece el buffer *grep* vemos que la lista de apariciones muestra tiene la forma:

    ./nombre-fichero:núm:texto de la línea

    La parte nombre-fichero:núm son enlaces. Es decir, si voy al buffer *grep* y pulso <RET> sobre ese encabezado de la línea, emacs abrirá el fichero en un buffer con el cursor situado en la línea marcada.

Conclusiones

Una forma de acelerar el trabajo, las consultas, las modificaciones en proyectos con muchos ficheros implicados, como un blog.


Comentarios