grep -rn --exclude-dir={.git,node_modules,vendor} 'TODO' . encuentra todas las coincidencias sin entrar en los tres directorios que arruinan casi cualquier grep recursivo en un repositorio real. --exclude-dir solo funciona junto con -r, y compara el nombre del directorio, no la ruta. Esta es la receta completa, desde la búsqueda recursiva ingenua hasta el punto en el que conviene instalar ripgrep.
1. Buscar en todo el proyecto
$ clai busca TODO en todos los archivos dentro de g→ grep -rn 'TODO' g/g/src/a.js:1:TODO fixg/node_modules/b.js:1:TODO dep
-r recorre subdirectorios, -n añade el número de línea. El problema se ve enseguida: la mitad de los resultados vienen de código ajeno.
2. Excluir un directorio
$ clai busca TODO pero no entres en node_modules→ grep -rn --exclude-dir=node_modules 'TODO' g/g/src/a.js:1:TODO fix
--exclude-dir solo funciona junto con -r. El nombre del directorio es un patrón, no una ruta — no le pongas barras.
3. Excluir varios a la vez
$ clai busca TODO, salta node_modules, .git y vendor→ grep -rn --exclude-dir={.git,node_modules,vendor} 'TODO' .
La shell expande las llaves antes de que grep se ejecute, así que grep recibe tres flags separados. En un sh sin brace expansion tendrás que escribir tres --exclude-dir seguidos.
4. Buscar solo en los archivos que importan
$ clai busca TODO solo en archivos javascript→ grep -rn --include='*.js' 'TODO' .
--include es una lista blanca. Cuando ya sabes dónde buscar, es más corto y más rápido que una larga cadena de exclusiones.
5. No tropezar con binarios
$ clai busca TODO ignorando archivos binarios→ grep -rnI 'TODO' .
Sin -I, grep imprime "Binary file … matches" en cada coincidencia binaria en vez de una línea — ensucia la salida y rompe cualquier script que la procese. -I simplemente se salta esos archivos.
6. Cuando los flags se acumulan
$ clai busca TODO en el proyecto respetando el gitignore→ rg 'TODO'
ripgrep lee .gitignore por defecto, se salta .git y los binarios — todo lo anterior sin un solo flag, y más rápido. Si hoy es la tercera vez que escribes una cadena larga de --exclude-dir, es hora de instalarlo.
Trampas
--exclude-dirsin-rno hace nada, en silencio. El flag se acepta pero nunca se aplica, y pensarás que está roto.- El patrón de
--exclude-dirno es una ruta.--exclude-dir=src/vendorno coincidirá con nada, porque grep compara el nombre del directorio, no la ruta hasta él. Escribe--exclude-dir=vendor. - Pon el patrón entre comillas.
grep -r --include=*.jsdeja que la shell expanda*.jscontra el directorio actual antes de que grep lo vea, y obtienes una búsqueda completamente distinta.
Preguntas relacionadas
¿Cómo excluyo el propio directorio .git? --exclude-dir=.git. El punto inicial no cambia nada — ejecutar -r sobre un repositorio sin este flag vuelca basura del almacén de objetos de git.
¿Cómo cuento coincidencias en vez de mostrarlas? grep -rc 'TODO' . imprime un conteo por archivo; grep -rho 'TODO' . | wc -l da el total de apariciones.
¿grep o ripgrep? grep está en todas partes y hay que conocerlo. ripgrep es más rápido y sensato por defecto, pero hay que instalarlo, y en un servidor ajeno eso no siempre es posible.
Ver también
- Buscar y reemplazar en todos los archivos de un proyecto
- Imprimir una columna de un CSV con awk
- JSON en la línea de comandos
Deja de memorizar flags de exclusión — describe qué buscas y CliAI escribe el grep. Instálalo en una línea.