🔍🐧 El comando find en Linux
El comando find de Linux es una de las herramientas más potentes y versátiles que existen para buscar archivos y directorios en el sistema de archivos. Si trabajas con la terminal (y si estás leyendo esto, asumo que sí o que quieres empezar), dominar find es prácticamente obligatorio.
En este artículo vamos a ver cómo usarlo desde lo más básico hasta combinaciones avanzadas que te harán sentir como un hacker de película. También hay ejercicios prácticos para que practiques con esta herramienta.
Sintaxis básica
La sintaxis general del comando find es la siguiente:
find [ruta] [opciones] [expresión]
Donde:
[ruta]es el directorio donde empieza la búsqueda. Usa.para el directorio actual,~para tu home,/para todo el sistema.[opciones]controlan el comportamiento de la búsqueda (profundidad, seguir symlinks…).[expresión]son los criterios de búsqueda y las acciones a ejecutar.
Si no le pasas ruta, find busca en el directorio actual. Si no le pasas expresión, devuelve todo lo que encuentra.
Opciones de búsqueda
Estas son las opciones que vas a usar el 90% del tiempo:
Busca por nombre de archivo. Sensible a mayúsculas/minúsculas. Acepta wildcards (*, ?).
Igual que -name pero insensible a mayúsculas/minúsculas. Muy útil cuando no recuerdas si el archivo era .JPG o .jpg.
f = archivos, d = directorios, l = symlinks, b = dispositivos de bloque, s = sockets.
Busca por tamaño. Usa + para "mayor que", - para "menor que". Sufijos: c (bytes), k (KB), M (MB), G (GB).
Busca por fecha de modificación en días. -mtime -7 = modificados hace menos de 7 días. -mtime +30 = hace más de 30 días.
Igual que -mtime pero en minutos. -mmin -60 = modificados en la última hora. Perfecto para buscar cambios recientes.
Busca por propietario del archivo. -user root = archivos que pertenecen a root.
Busca por permisos. -perm 755 = permisos exactos. -perm -644 = al menos esos permisos.
Busca archivos o directorios vacíos. Combinado con -delete es perfecto para limpiar basura.
Controla la profundidad de la búsqueda. -maxdepth 1 = solo el directorio actual, sin subdirectorios.
Ejemplos básicos
Buscar por nombre
# Buscar todos los .txt en el directorio actual y subdirectorios
find . -name "*.txt"
# Lo mismo pero sin importar mayúsculas/minúsculas
find . -iname "*.txt"
# Buscar un archivo concreto
find / -name "php.ini" 2>/dev/null
El 2>/dev/null al final redirige los errores de permisos a la nada. Sin esto, te va a saltar un montón de “Permission denied” si buscas desde la raíz.
Buscar por tipo
# Solo directorios
find . -type d -name "config"
# Solo archivos
find . -type f -name "*.log"
# Solo symlinks
find . -type l
Buscar por tamaño
# Archivos mayores de 100MB
find . -type f -size +100M
# Archivos menores de 1KB (posiblemente vacíos o residuales)
find . -type f -size -1k
# Archivos de exactamente 0 bytes
find . -type f -empty
Buscar por fecha
# Modificados en los últimos 7 días
find . -type f -mtime -7
# Modificados hace más de 30 días
find . -type f -mtime +30
# Modificados en la última hora
find . -type f -mmin -60
# Archivos que NO se han tocado en 90 días
find . -type f -mtime +90
Buscar por permisos y propietario
# Archivos con permisos 755
find . -type f -perm 755
# Archivos que pertenecen a un usuario concreto
find . -type f -user www-data
# Archivos que NO pertenecen a ningún usuario del sistema
find . -nouser
Combinando criterios
Aquí es donde find empieza a brillar de verdad. Puedes combinar criterios con operadores lógicos:
Se cumple si ambas condiciones son verdaderas. Es el operador por defecto (no hace falta escribirlo).
Se cumple si al menos una condición es verdadera.
Niega la condición. Encuentra todo lo que NO cumple el criterio.
# Archivos .jpg O .png (nota los paréntesis escapados)
find . -type f \( -name "*.jpg" -or -name "*.png" \)
# Archivos .log que pesan más de 10MB
find . -type f -name "*.log" -size +10M
# Archivos que NO son .txt
find . -type f -not -name "*.txt"
# Archivos .conf modificados en la última semana
find /etc -type f -name "*.conf" -mtime -7
# Directorios vacíos que NO son .git
find . -type d -empty -not -name ".git"
Acciones: -exec, -delete y -print
Buscar archivos está bien, pero la magia de find es que puedes ejecutar acciones sobre los resultados. Aquí es donde se convierte en una herramienta brutalmente potente.
-exec: ejecutar un comando por cada resultado
# Ver detalles (ls -lh) de cada archivo encontrado
find . -type f -name "*.log" -exec ls -lh {} \;
# Cambiar permisos de todos los scripts .sh
find . -type f -name "*.sh" -exec chmod +x {} \;
# Buscar texto dentro de archivos específicos
find . -type f -name "*.php" -exec grep -l "TODO" {} \;
# Copiar todos los .pdf a un directorio de backup
find . -type f -name "*.pdf" -exec cp {} /backup/pdfs/ \;
El {} se reemplaza por cada archivo encontrado. El \; indica el final del comando. Es la sintaxis más fea del mundo, pero funciona de maravilla.
-exec con + en lugar de \;
# Más eficiente: pasa todos los archivos de una vez al comando
find . -type f -name "*.tmp" -exec rm {} +
La diferencia entre \; y + es importante:
\;ejecuta el comando una vez por cada archivo encontrado. Si hay 1000 archivos, ejecuta 1000 vecesrm.+agrupa los archivos y ejecuta el comando las menos veces posible. Mucho más eficiente.
-delete: borrar directamente
# Borrar todos los archivos .tmp
find . -type f -name "*.tmp" -delete
# Borrar directorios vacíos
find . -type d -empty -delete
Cuidado con -delete. No pide confirmación y no manda nada a la papelera. Lo que borras con -delete desaparece para siempre. Siempre ejecuta el find sin -delete primero para ver qué va a borrar, y cuando estés seguro, añade el -delete.
Combinar find con xargs
xargs es el compañero perfecto de find. Toma la salida de find y la pasa como argumentos a otro comando:
# Buscar en archivos PHP la palabra "deprecated"
find . -type f -name "*.php" | xargs grep "deprecated"
# Lo mismo pero manejando nombres con espacios
find . -type f -name "*.php" -print0 | xargs -0 grep "deprecated"
# Comprimir todos los .log antiguos
find /var/log -type f -name "*.log" -mtime +30 -print0 | xargs -0 gzip
El -print0 y -0 usan el carácter nulo como separador en lugar de saltos de línea. Esto es importante cuando los nombres de archivo tienen espacios o caracteres raros.
Expresiones regulares con -regex
Para búsquedas más complejas puedes usar expresiones regulares:
# Archivos que terminan en .jpg, .jpeg o .png
find . -type f -regex ".*\.\(jpg\|jpeg\|png\)"
# Con la sintaxis extendida de regex (más legible)
find . -type f -regextype posix-extended -regex ".*\.(jpg|jpeg|png)"
# Archivos que empiezan por "backup_" seguido de una fecha
find . -type f -regextype posix-extended -regex ".*backup_[0-9]{4}-[0-9]{2}-[0-9]{2}.*"
Casos de uso reales
Estos son comandos que uso en el día a día como desarrollador y que te van a servir seguro:
Limpieza de sistema
# Encontrar los 10 archivos más grandes del sistema
find / -type f -exec du -h {} + 2>/dev/null | sort -rh | head -10
# Encontrar archivos de más de 600MB
find / -type f -size +600M 2>/dev/null
# Limpiar archivos temporales de más de 7 días
find /tmp -type f -mtime +7 -delete
# Borrar logs viejos de más de 30 días
find /var/log -type f -name "*.log" -mtime +30 -exec rm -f {} \;
# Borrar archivos .DS_Store (si trabajas con macOS)
find . -name ".DS_Store" -delete
Seguridad y auditoría
# Archivos con permisos de escritura para todos (inseguro)
find /var/www -type f -perm -o=w
# Archivos SUID (pueden ser un riesgo de seguridad)
find / -type f -perm -4000 2>/dev/null
# Archivos sin propietario (posible indicador de intrusión)
find / -nouser -o -nogroup 2>/dev/null
# Archivos modificados en las últimas 24h (útil tras un incidente)
find / -type f -mtime -1 2>/dev/null
# Buscar archivos ocultos sospechosos en /tmp
find /tmp -name ".*" -type f
Desarrollo y proyectos
# Buscar todos los TODO y FIXME en tu proyecto
find . -type f -name "*.php" -exec grep -Hn "TODO\|FIXME" {} \;
# Encontrar archivos de configuración modificados recientemente
find /etc -type f -name "*.conf" -mmin -60
# Listar todos los archivos de un proyecto excluyendo vendor y node_modules
find . -type f -not -path "*/vendor/*" -not -path "*/node_modules/*"
# Contar líneas de código PHP en un proyecto
find . -type f -name "*.php" -not -path "*/vendor/*" | xargs wc -l | tail -1
# Buscar archivos duplicados por nombre
find . -type f -name "*.js" | sed 's|.*/||' | sort | uniq -d
Tabla de referencia rápida
| Opción | Ejemplo | Descripción |
|---|---|---|
-name | -name "*.txt" | Por nombre (case sensitive) |
-iname | -iname "*.JPG" | Por nombre (case insensitive) |
-type f | -type f | Solo archivos regulares |
-type d | -type d | Solo directorios |
-size | -size +100M | Por tamaño (+ mayor, - menor) |
-mtime | -mtime -7 | Modificado hace N días |
-mmin | -mmin -60 | Modificado hace N minutos |
-user | -user root | Por propietario |
-perm | -perm 755 | Por permisos |
-empty | -empty | Archivos/directorios vacíos |
-maxdepth | -maxdepth 2 | Limitar profundidad |
-exec | -exec ls -lh {} \; | Ejecutar comando por resultado |
-delete | -delete | Borrar resultados (sin confirmación) |
Ejercicios prácticos
Para practicar el uso del comando find, realiza los siguientes ejercicios:
- Encuentra todos los archivos con extensión
.logen/var/logy sus subdirectorios. - Busca todos los archivos ejecutables (permisos 755) en tu directorio home.
- Encuentra todos los archivos modificados en las últimas 24 horas en
/tmp. - Busca todos los archivos de más de 50MB en el sistema y muestra su tamaño en formato legible.
- Encuentra todos los archivos vacíos en tu directorio de documentos y elimínalos.
- Busca todos los archivos
.phpque contengan la palabra “password” (posible problema de seguridad). - Encuentra todos los directorios llamados “cache” o “tmp” y muestra cuánto espacio ocupan.
- Lista todos los symlinks rotos en tu sistema.
Soluciones
-
find /var/log -name "*.log" -
find ~ -type f -perm 755 -
find /tmp -type f -mtime -1 -
find / -type f -size +50M -exec ls -lh {} + 2>/dev/null -
find ~/Documents -type f -empty -delete -
find . -type f -name "*.php" -exec grep -l "password" {} + -
find / -type d \( -name "cache" -or -name "tmp" \) -exec du -sh {} + 2>/dev/null -
find / -xtype l 2>/dev/null
Practicar estos ejercicios te ayudará a familiarizarte con el comando find y sus diversas opciones. Recuerda siempre consultar la página del manual (man find) para obtener información detallada sobre todas las opciones disponibles.
Conclusión
El comando find es una de esas herramientas que cuanto más la usas, más te das cuenta de lo potente que es. Desde buscar un archivo perdido hasta limpiar un servidor entero de basura, auditar permisos de seguridad o automatizar tareas de mantenimiento.
Las claves para dominar find son:
- Empieza simple:
find . -name "algo"y ve añadiendo filtros. - Siempre prueba antes de borrar: Ejecuta sin
-deleteprimero. - Combina con otros comandos:
xargs,grep,wc,du…findse vuelve imparable cuando lo combinas. - Usa
2>/dev/null: Para no llenarte la pantalla de errores de permisos.
EA ¡nos leemos! 🍻
Pon a prueba lo aprendido
1. ¿Cuál es la diferencia entre -name y -iname en find?
2. ¿Qué hace el comando: find . -type f -size +100M?
3. ¿Qué significa -mtime -7 en find?
4. ¿Cuál es la diferencia entre -exec ... \\; y -exec ... + ?
5. ¿Por qué se usa 2>/dev/null al final de un comando find?
6. ¿Qué precaución hay que tomar SIEMPRE antes de usar -delete?
7. ¿Para qué sirve -print0 combinado con xargs -0?
8. ¿Qué encuentra el comando: find / -type f -perm -4000?