Linux
7 minutos Publicado el 25/04/2026Grep
Todos estuvimos horas buscando entre archivos una línea de código que recordamos haber escrito y que necesitamos una vez más para el proyecto actual en el que estamos. Una línea de código, como una configuración, que en su momento buscamos en foros, respuestas, tutoriales de blogs o artículos, la encontramos, la implementamos y anduvo. Recordamos también que no había sido simple dar con la solución, por lo que desesperados abrimos y cerramos archivos de proyectos intentando evitar tener que salir a buscarla una vez más.
En los inicios de Unix, al tener una capacidad reducida de memoria y espacio, Ken Thompson y Dennis Ritchie crearon un programa llamado Ed para editar texto. Este se utilizaba por medio de comandos como p para imprimir, w para escribir, r para leer o d para borrar.
En el equipo se encontraba trabajando el lingüista Lee McMahon, quien quería buscar coincidencias exactas de texto para analizar los Federalist Papers y determinar su autoría. El problema era que el tamaño de los textos era demasiado grande y la memoria del sistema no permitía abrirlos por completo en Ed. A su vez, Doug McIlroy también necesitaba buscar patrones de texto para un programa de síntesis de voz. Le comentaron este obstáculo a Ken Thompson, quien en una sola noche extrajo la lógica de búsqueda de Ed y creó un programa independiente capaz de leer archivos línea por línea sin saturar la memoria.
En Ed ya existía un comando llamado Global (g), el cual se encargaba de tomar todas las apariciones para luego cambiarlas, imprimirlas o borrarlas.
Por ejemplo, si se quería borrar una misma palabra en todo un texto se colocaba:
g /word/ d
Esto indicaba que de manera global buscara las coincidencias y las borrara con el comando delete (d), y si se quería imprimir, en lugar de colocar d se ponía p de print.
Lo que hizo Ken Thompson fue adaptar estas funciones de Ed para que se pudieran utilizar con expresiones regulares y tener coincidencias exactas de patrones de texto. Por lo que ahora el programa podía: de manera Global (g), buscar Expresiones regulares (re) e imprimirlas (p). g/re/p. Grep significa eso, Global Regular Expression Print.
¿Qué es Grep?
Es una herramienta de terminal (consola) que nos permite buscar patrones de texto en uno o más archivos o en entradas estándar, imprimiendo el resultado en pantalla.
La manera básica de utilizarlo es colocando grep, luego la palabra que queremos buscar y finalmente la ruta del archivo en donde queremos que busque:
grep <palabra> ./ruta/a/tu/archivo
En caso de que encuentre una o varias coincidencias, imprimirá la línea completa en la que se encuentra. Si queremos que encuentre todas las coincidencias, sin importar si están en mayúsculas o minúsculas, entonces podemos utilizar la bandera -i:
grep -i <palabra> ./ruta/a/tu/archivo
Pero si lo que queremos saber es en qué línea se encuentra la coincidencia, entonces utilizamos la bandera -n:
grep -n <palabra> ./ruta/a/tu/archivo
Algo que debemos saber es que podemos combinar las banderas. Por lo que, si queremos saber en qué línea se encuentra una palabra y no sabemos si está escrita con mayúsculas o minúsculas, podemos usar la suma de -n e -i, que sería -ni.
Otra bandera muy utilizada es -r, la cual permite que Grep realice una búsqueda de manera recursiva. Esto es útil cuando no sabemos en qué archivo pueda encontrarse el texto, por lo que realiza una búsqueda por todos los archivos de la carpeta que le indiquemos:
grep -r <palabra> .
Al colocar . le indicamos que la búsqueda la realice en la carpeta en la que nos encontramos. Si a esta bandera le sumamos la de búsqueda entre mayúsculas y minúsculas y el número de línea, podemos ver todos los archivos en donde haya coincidencia y la línea en la que se encuentra en cada uno de ellos: -rni.
Si la respuesta que obtenemos es extensa, podemos indicarle que solamente busque en determinados archivos cuya extensión sea, por ejemplo, .cpp, con la ayuda de --include:
grep -rn --include="*.cpp" <palabra> .
Cuando utilizamos * estamos diciendo todos. Así, con *.cpp podemos indicar que lo haga en todos los archivos que finalicen con esa extensión.
De la misma manera que podemos incluir archivos, podemos excluir directorios si sabemos que hay algunos que son pesados y en donde no está lo que buscamos, como pueden ser las librerías:
grep -rn --exclude-dir=<folder> <palabra> .
De esta manera será más limpia la búsqueda que realicemos. Pero hay veces en las que necesitamos el contexto del texto encontrado, para lo cual existe -C, el cual nos trae una cantidad específica de líneas anteriores y posteriores:
grep -rnC 3 --exclude-dir=<folder> <palabra> .
Esto traerá el resultado separado en bloques para que podamos visualizar mejor lo que encontró en cada uno de los archivos.
Otra bandera fundamental es -v, la cual funciona para invertir la búsqueda. Es decir, en lugar de mostrarnos las líneas que coinciden con el patrón, nos mostrará todas las que no coincidan. Es muy útil para filtrar resultados no deseados:
grep -v <palabra> ./ruta/a/tu/archivo
Por otro lado, si estamos buscando un patrón en múltiples archivos pero no nos interesa ver la línea exacta ni el contexto, sino únicamente saber en qué archivos se encuentra, utilizamos la bandera -l (list):
grep -rl <palabra> .
Esto devolverá una lista limpia con las rutas de los archivos que contienen la coincidencia, ideal para luego pasar esa lista a otro comando o para iterar sobre ellos.
Pipes
Los pipes (|) sirven para obtener el output (salida) de un comando y llevarlo como entrada a otro comando. Por ejemplo, si queremos ver todos los servicios que se encuentran corriendo en nuestro SO, podemos poner:
ps aux
Pero si dentro de la salida que nos dan queremos ver solamente aquellos de un programa en particular, podemos utilizar Grep para que nos ayude:
ps aux | grep <programa>
Otro ejemplo que suelo utilizar es cuando estoy leyendo documentación en man. Como utilizo Neovim, prefiero leerlo en el editor de texto, por lo que suelo hacer:
man grep | nvim -
man grep tiene como salida el texto con todos los comandos y modos de uso de Grep. Al usar el pipe, hacemos que esa salida se redirija hacia Neovim. (Nota técnica: es necesario agregar el guion final - para que el editor sepa que debe leer desde la entrada estándar).
Un uso cotidiano de los pipes con Grep es la búsqueda dentro de nuestro propio historial de comandos. Si recordamos haber ejecutado un comando complejo (por ejemplo, de Docker o Git) pero no recordamos la sintaxis exacta, podemos filtrar el historial:
history | grep docker
También podemos encadenar múltiples comandos Grep mediante pipes para realizar filtrados más precisos. Por ejemplo, si estamos leyendo un archivo de logs y queremos ver los errores, pero excluir aquellos que sean simples advertencias (warnings), podemos combinar la búsqueda normal con la bandera -v:
cat system.log | grep -i "error" | grep -v -i "warning"
En este caso, el primer Grep toma la salida del archivo y filtra solo las líneas con la palabra “error”. Luego, esa salida filtrada pasa al segundo Grep, el cual elimina cualquier línea que contenga la palabra “warning”.