Comando find de Linux: opciones -name, -type, -size, -mtime y -delete
El comando find de Linux recorre hacia abajo una carpeta de inicio y encuentra archivos y carpetas que cumplen condiciones como nombre, tipo, tamaño, fecha de modificación y permisos. Al crear diez archivos en una carpeta de prueba de un servidor AlmaLinux 9 y ejecutarlo cambiando una condición cada vez, terminamos pasando los archivos encontrados con -exec a otros comandos y, al borrar, revisando antes la lista con las mismas condiciones y usando -delete después.
Las rutas de la carpeta de prueba y las fechas de los archivos en los cuadros de resultado se cambiaron por valores de ejemplo. En la salida del servidor Debian 12, solo la ruta de la carpeta personal es un valor de ejemplo y el resto está tal cual.
1️⃣ Cómo usar el comando find de Linux
La forma básica es [find ruta-de-inicio condiciones]. Si omites la ruta de inicio, busca en la carpeta actual (.), y si omites las condiciones, imprime todos los archivos y carpetas bajo la ruta de inicio.
La prueba se hizo en /root/work, con tres carpetas y diez archivos como se ve abajo.
find /root/work/root/work
/root/work/docs
/root/work/docs/readme.txt
/root/work/docs/guide.txt
/root/work/docs/old.tmp
/root/work/logs
/root/work/logs/app.log
/root/work/logs/cache.tmp
/root/work/backup
/root/work/report.txt
/root/work/README.md
/root/work/run.sh
/root/work/my notes.txt
/root/work/empty.txtfind no ordena los resultados por nombre; en esta ejecución, al llegar a la carpeta docs imprimió primero todos sus archivos y luego pasó a logs.
Si encadenas varias condiciones, solo quedan los archivos que cumplen todas.
-name compara con el patrón solo el nombre del archivo, no la ruta. Envuelve el patrón entre comillas simples para que el shell no expanda * antes y lo pase tal cual a find.
find /root/work -name '*.txt'/root/work/docs/readme.txt
/root/work/docs/guide.txt
/root/work/report.txt
/root/work/my notes.txt
/root/work/empty.txt-name distingue mayúsculas y minúsculas. Al buscar nombres que empiezan por readme solo salió docs/readme.txt, y al cambiar a -iname salió también README.md.
find /root/work -name 'readme*'/root/work/docs/readme.txtfind /root/work -iname 'readme*'/root/work/docs/readme.txt
/root/work/README.mdfind está en el paquete findutils. La versión de la primera línea de [find --version] fue findutils 4.8 en el servidor AlmaLinux 9.8 y 4.9 en el servidor Debian 12.
2️⃣ find -type d y -maxdepth
-type f deja solo archivos normales y -type d deja solo carpetas.
find /root/work -type d/root/work
/root/work/docs
/root/work/logs
/root/work/backupLa ruta de inicio /root/work también es una carpeta, así que salió en la primera línea. Al cambiar a -type f en la misma ruta salieron los diez archivos.
-maxdepth fija cuántos niveles baja desde la ruta de inicio. Con -maxdepth 1 quedaron fuera los archivos de docs y logs, y solo quedaron los cinco archivos justo debajo de /root/work.
find /root/work -maxdepth 1 -type f/root/work/report.txt
/root/work/README.md
/root/work/run.sh
/root/work/my notes.txt
/root/work/empty.txtAl contrario, -mindepth 2 saltó lo que hay justo debajo de la ruta de inicio e imprimió solo los cinco archivos dentro de subcarpetas.
find /root/work -mindepth 2 -type f/root/work/docs/readme.txt
/root/work/docs/guide.txt
/root/work/docs/old.tmp
/root/work/logs/app.log
/root/work/logs/cache.tmpLa página man indica escribir opciones globales como -maxdepth justo después de la ruta de inicio. Escribir -maxdepth 1 detrás de -type f dio los mismos cinco archivos, y en una terminal sale una línea de aviso que pide poner las opciones globales delante (según la página man).
Para ver solo cuántas carpetas o archivos hay, pasa la salida a wc -l. Al contar la salida de -type d salió 4, incluida la ruta de inicio.
find /root/work -type d | wc -l4Con -maxdepth 1 también salió 4, porque las tres subcarpetas están justo debajo de la ruta de inicio.
find /root/work -maxdepth 1 -type d | wc -l4Al contar con -mindepth 2 solo los archivos dentro de subcarpetas salió 5.
find /root/work -mindepth 2 -type f | wc -l53️⃣ Condiciones de tamaño y tiempo del comando find
El + delante de un número significa mayor que ese valor, - significa menor, y sin signo es exactamente ese valor. Las unidades de -size están en la tabla de abajo (según la página man).
| Unidad | Tamaño | Sí |
|---|---|---|
| c | 1 byte | -size +500c |
| k | 1,024 bytes | -size +1k |
| M | 1,048,576 bytes | -size +1M |
| G | 1,073,741,824 bytes | -size +1G |
| (ninguna) | Bloques de 512 bytes | -size +2 |
find /root/work -type f -size +1k/root/work/docs/guide.txt
/root/work/logs/app.log
/root/work/report.txtLos archivos mayores de 1k fueron guide.txt con 5,000 bytes, app.log con 2MB y report.txt con 1,200 bytes.
find /root/work -size +1M/root/work/logs/app.logAl escribir -size dos veces para fijar un rango, solo quedaron los dos archivos mayores de 1k y menores de 100k.
find /root/work -type f -size +1k -size -100k/root/work/docs/guide.txt
/root/work/report.txt-size divide el tamaño por la unidad y redondea hacia arriba antes de comparar. Por eso README.md, con 300 bytes, también cuenta como 1k, y con -size -1k solo salió empty.txt, de tamaño 0.
find /root/work -type f -size -1k/root/work/empty.txtPara probar las condiciones de tiempo, ajustamos la fecha de modificación de README.md, my notes.txt y docs/readme.txt a hace 3 días, y la de los dos archivos .tmp a hace 10 días. Cada archivo guarda tres fechas, de acceso, modificación y cambio, que puedes consultar con el comando stat.
-mtime cuenta el tiempo desde la última modificación en unidades de 24 horas. Con -mtime -1 salieron los cinco archivos creados en las últimas 24 horas.
find /root/work -type f -mtime -1/root/work/docs/guide.txt
/root/work/logs/app.log
/root/work/report.txt
/root/work/run.sh
/root/work/empty.txtCon -mtime +7 solo salieron los dos archivos .tmp ajustados a hace 10 días. Usa esta forma para revisar la lista antes de borrar registros antiguos o archivos temporales.
find /root/work -type f -mtime +7/root/work/docs/old.tmp
/root/work/logs/cache.tmp-mmin hace el mismo cálculo en minutos. El resultado de -mmin -60 fueron los mismos cinco archivos que con -mtime -1.
find /root/work -type f -mmin -60/root/work/docs/guide.txt
/root/work/logs/app.log
/root/work/report.txt
/root/work/run.sh
/root/work/empty.txt-newer busca archivos modificados después de un archivo de referencia. Con README.md, ajustado a hace 3 días, como referencia, salieron los cinco archivos creados después.
find /root/work -type f -newer /root/work/README.md/root/work/docs/guide.txt
/root/work/logs/app.log
/root/work/report.txt
/root/work/run.sh
/root/work/empty.txt-empty busca a la vez archivos de tamaño 0 y carpetas vacías, y salieron la carpeta vacía backup y empty.txt.
find /root/work -empty/root/work/backup
/root/work/empty.txt4️⃣ Condiciones -perm y -user de find
Si tras -perm escribes solo un número, busca archivos con permisos exactamente de ese valor. Con -perm 644 quedaron fuera run.sh, con 755, y my notes.txt, con 600, y salieron ocho.
find /root/work -type f -perm 644/root/work/docs/readme.txt
/root/work/docs/guide.txt
/root/work/docs/old.tmp
/root/work/logs/app.log
/root/work/logs/cache.tmp
/root/work/report.txt
/root/work/README.md
/root/work/empty.txtCon - delante del modo busca archivos que tengan todos los permisos indicados. Solo run.sh tenía permiso de ejecución del propietario (u+x).
find /root/work -type f -perm -u+x/root/work/run.shCon / delante del modo basta con tener uno de los permisos indicados. 6000 es la suma de SUID (4000) y SGID (2000), y esta forma sirve para revisar en el servidor los archivos que, al ejecutarse, actúan con los permisos de su propietario o grupo.
La carpeta de prueba no tenía ninguno, así que dimos SUID a run.sh y al ejecutarlo salió run.sh.
chmod u+s /root/work/run.shfind /root/work -type f -perm /6000/root/work/run.shEn materiales antiguos aparece -perm +6000 en ese lugar. Al ejecutarlo tal cual terminó con el error [invalid mode].
find /root/work -type f -perm +6000find: invalid mode '+6000'La forma + se eliminó en findutils 4.5.12 (según la página man), así que escribe /. El SUID puesto para la prueba se quitó con chmod u-s.
-user filtra por nombre de propietario. Todos los archivos de prueba son de root, así que -user root no filtra nada por sí solo; al añadir -name para elegir archivos .log salió solo app.log.
find /root/work -type f -user root -name '*.log'/root/work/logs/app.log-nouser busca archivos cuyo UID de propietario no tiene cuenta. Sirve para revisar archivos que quedan en el servidor tras borrar una cuenta; al cambiar el propietario de guide.txt al UID inexistente 1500, salió guide.txt.
chown 1500:1500 /root/work/docs/guide.txtfind /root/work -nouser/root/work/docs/guide.txt-nogroup hace la misma comprobación con el grupo propietario, y salió guide.txt, con el grupo también cambiado a 1500. Tras la prueba lo restauramos con chown root:root.
Con -o entre condiciones basta con que se cumpla una. Al usarlo con otra condición como -type f, agrupa entre paréntesis las condiciones unidas por -o. Pon una barra invertida delante de cada paréntesis para que el shell no lo interprete antes, y deja espacios entre paréntesis y condiciones.
find /root/work -type f \( -name '*.log' -o -name '*.tmp' \)/root/work/docs/old.tmp
/root/work/logs/app.log
/root/work/logs/cache.tmp! invierte la condición que le sigue. Al buscar archivos que no son .txt salieron cinco.
find /root/work -type f ! -name '*.txt'/root/work/docs/old.tmp
/root/work/logs/app.log
/root/work/logs/cache.tmp
/root/work/README.md
/root/work/run.sh5️⃣ Usar find -exec
-exec ejecuta el comando escrito detrás por cada archivo encontrado, con la ruta encontrada en lugar de {}. El ; final del comando se escribe \; para que el shell no lo lea antes como separador de comandos.
find /root/work -name '*.log' -exec ls -l {} \;-rw-r--r-- 1 root root 2097152 Oct 5 14:10 /root/work/logs/app.logSi terminas con + en lugar de \;, las rutas encontradas se reúnen y el comando se ejecuta una sola vez. Al comparar con echo, \; imprimió las cinco rutas en cinco líneas y + en una.
find /root/work -name '*.txt' -exec echo {} \;/root/work/docs/readme.txt
/root/work/docs/guide.txt
/root/work/report.txt
/root/work/my notes.txt
/root/work/empty.txtfind /root/work -name '*.txt' -exec echo {} +/root/work/docs/readme.txt /root/work/docs/guide.txt /root/work/report.txt /root/work/my notes.txt /root/work/empty.txtLos comandos que aceptan varias rutas, como ls, se agrupan con + para reducir las ejecuciones. Comprobamos el tamaño de los tres archivos mayores de 1k con un solo ls -lh.
find /root/work -type f -size +1k -exec ls -lh {} +-rw-r--r-- 1 root root 4.9K Oct 5 14:10 /root/work/docs/guide.txt
-rw-r--r-- 1 root root 2.0M Oct 5 14:10 /root/work/logs/app.log
-rw-r--r-- 1 root root 1.2K Oct 5 14:10 /root/work/report.txt-exec también sirve para fijar de golpe los permisos de una carpeta web, 644 para archivos y 755 para carpetas. Antes de ejecutarlo buscamos los archivos con otro valor y salieron run.sh y my notes.txt.
find /root/work -type f ! -perm 644/root/work/run.sh
/root/work/my notes.txtArchivos y carpetas llevan permisos distintos, así que se ejecuta por separado con -type f y -type d. chmod también acepta varias rutas, por lo que terminamos con +.
find /root/work -type f -exec chmod 644 {} +find /root/work -type d -exec chmod 755 {} +Al buscar de nuevo con la misma condición no salió nada, y la carpeta backup, cambiada antes a 700, también pasó a 755.
Pero run.sh también pasó a 644, y al ejecutarlo salió [Permission denied]. En carpetas con ejecutables mezclados, devuelve el permiso de ejecución a esos archivos con chmod +x.
Para cambiar solo los archivos dentro de subcarpetas, añade -mindepth 2. Con 660 solo cambiaron los cinco archivos de docs y logs, y tras comprobarlo volvimos a 644.
find /root/work -mindepth 2 -type f -exec chmod 660 {} +find /root/work -type f -perm 660/root/work/docs/readme.txt
/root/work/docs/guide.txt
/root/work/docs/old.tmp
/root/work/logs/app.log
/root/work/logs/cache.tmpAl unir find y grep buscas por el contenido del archivo y no por el nombre. Para simular una revisión de web shells, creamos cuatro archivos PHP en la carpeta aparte /root/site y pusimos la cadena [base64_decode] en html-cache.php y photo.php de la carpeta upload.
find /root/site -type f/root/site/lib/func.php
/root/site/upload/html-cache.php
/root/site/upload/photo.php
/root/site/index.phpSi conoces el nombre del web shell, búscalo con -name. Al añadir -maxdepth 2 para bajar solo hasta la carpeta upload salió solo html-cache.php.
find /root/site -maxdepth 2 -type f -name 'html*.php'/root/site/upload/html-cache.phpphoto.php, con un nombre corriente, no salió aquí. Al ejecutar grep -l con -exec se imprimen solo las rutas de los archivos con la cadena, y salieron los dos.
find /root/site -name '*.php' -exec grep -l 'base64_decode' {} +/root/site/upload/html-cache.php
/root/site/upload/photo.php[base64_decode] es una función que también aparece en archivos del núcleo de WordPress, así que abre y revisa el contenido de los archivos encontrados antes de borrarlos.
-print0 pone un carácter nulo en lugar de un salto de línea entre rutas. El carácter nulo no se ve en pantalla, así que las rutas salieron unidas en una línea.
find /root/work -name '*.txt' -print0/root/work/docs/readme.txt/root/work/docs/guide.txt/root/work/report.txt/root/work/my notes.txt/root/work/empty.txtPara pasar a otro comando nombres con espacios como my notes.txt sin que se corten, la salida de -print0 se usa en pareja con xargs -0 (según la página man).
6️⃣ Eliminar archivos con find y opciones
Antes de borrar, ejecuta primero las mismas condiciones sin borrar y revisa a ojo la lista de archivos que se borrarán.
find /root/work -name '*.tmp'/root/work/docs/old.tmp
/root/work/logs/cache.tmp-exec rm {} \; ejecuta rm por cada archivo encontrado. Al ejecutarlo solo en la carpeta logs se borró cache.tmp y quedó solo app.log.
find /root/work/logs -name '*.tmp' -exec rm {} \;ls /root/work/logsapp.log-delete hace que find borre directamente sin ejecutar rm. Al ejecutarlo no imprimió nada, y al buscar de nuevo con la misma condición no quedaban archivos .tmp.
find /root/work -name '*.tmp' -deletefind /root/work -name '*.tmp'-delete debe ir siempre detrás de las condiciones. find evalúa la línea de comando desde el principio como una sola expresión, así que con -delete al principio intenta borrar todo lo que hay bajo la ruta de inicio antes de mirar ninguna condición (según la página man).
🔲 Opciones del comando find
📌 Opciones principales: resultados de este artículo
| Opción | Tarea | Resultado en este artículo | |
|---|---|---|---|
| -name | Busca nombres que coinciden con un patrón (distingue mayúsculas) | '*.txt' da cinco archivos; 'readme*' solo docs/readme.txt | |
| -iname | Compara nombres sin distinguir mayúsculas | 'readme*' da docs/readme.txt y README.md | |
| -type f, -type d | Deja solo archivos normales (f) o carpetas (d) | -type d da cuatro carpetas con la ruta de inicio; -type f da diez archivos | |
| -maxdepth | Baja solo hasta N niveles bajo la ruta de inicio | -maxdepth 1 deja solo los cinco archivos justo debajo de /root/work | |
| -mindepth | Salta los niveles por encima de N desde la ruta de inicio | -mindepth 2 da solo los cinco archivos dentro de subcarpetas | |
| -size | Busca por tamaño (+ mayor, - menor, unidades c, k, M, G) | -size +1k da tres archivos; -size -1k solo empty.txt | |
| -mtime | Compara el tiempo desde la modificación del contenido en unidades de 24 horas | -mtime -1 da cinco archivos; -mtime +7 dos archivos .tmp | |
| -mmin | Compara el tiempo desde la modificación en minutos | -mmin -60 da los mismos cinco archivos que -mtime -1 | |
| -ctime | Compara en unidades de 24 horas hasta el cambio de datos del archivo, como permisos y nombre | -ctime -1 da los diez archivos de prueba | |
| -newer | Busca lo modificado después de un archivo de referencia | Cinco archivos con README.md, ajustado a hace 3 días, como referencia | |
| -empty | Busca archivos de tamaño 0 y carpetas vacías | Da la carpeta vacía backup y empty.txt | |
| -perm | Busca por permisos (solo número: exactamente ese valor; con - delante: todos los indicados; con /: alguno de ellos) | -perm 644 da ocho archivos, -perm -u+x da run.sh y -perm /6000 da run.sh tras poner SUID | |
| -user | Filtra por nombre de propietario | Con -name '*.log' da app.log; una cuenta inexistente termina con error | |
| -nouser | Busca lo que tiene un UID de propietario sin cuenta | Da guide.txt, con el UID cambiado a 1500 | |
| -nogroup | Busca lo que tiene un GID de grupo sin grupo | Da guide.txt, con el GID cambiado a 1500 | |
| -o | Deja lo que cumple una de las dos (entre paréntesis si va con otras condiciones) | Agrupando .log y .tmp salen tres archivos | |
| ! | Invierte la condición que le sigue | Da cinco archivos que no son .txt | |
| -exec | Ejecuta el comando escrito detrás por cada archivo encontrado (ruta en lugar de {}) | Terminando con +, un solo echo imprime cinco rutas en una línea | |
| -print0 | Pone un carácter nulo en lugar de un salto de línea entre rutas | El carácter nulo no se ve y las rutas salen unidas en una línea | |
| -delete | find borra directamente los archivos encontrados (va detrás de las condiciones) | No imprimió nada; al buscar de nuevo no había archivos .tmp |
📎 Otras opciones: según el manual oficial
| Opción | Tarea | |
|---|---|---|
| -L | Sigue enlaces simbólicos y usa los datos del archivo de destino | |
| -path | Compara la ruta completa, no el nombre, con un patrón del shell | |
| -regex | Compara la ruta completa con una expresión regular | |
| -iregex | Compara como -regex, sin distinguir mayúsculas | |
| -atime | Compara el tiempo desde el último acceso en unidades de 24 horas | |
| -cnewer | Busca lo que cambió de estado después de la modificación del archivo de referencia | |
| -group | Filtra por nombre del grupo propietario | |
| -xdev | No baja a carpetas de otros sistemas de archivos | |
| -daystart | Calcula las condiciones de tiempo desde las 0:00 de hoy en lugar de hace 24 horas | |
| -prune | Si es una carpeta, no baja a ella | |
| -quit | Termina enseguida (-print -quit imprime solo el primer resultado) | |
| -printf | Imprime con el formato que definas | |
| -ls | Imprime los archivos encontrados con formato ls -dils | |
| -fprint | Guarda las rutas encontradas en un archivo indicado en lugar de la pantalla | |
| -ok | Ejecuta como -exec, pero pregunta antes | |
| -execdir | Ejecuta como -exec, pero en la carpeta del archivo encontrado |
🔲 Simulador del comando find
El simulador de abajo es un servidor virtual con la misma carpeta de prueba, donde puedes ejecutar tú mismo condiciones como -name, -type, -size, -mtime y -perm, además de -exec y -delete.
7️⃣ Errores del comando find
Si escribes un patrón sin comillas, el shell aplica las reglas de Comodines y lo expande antes en los nombres de archivo de la carpeta actual. Al ir a la carpeta docs y escribir *.txt sin comillas, el shell lo cambió por los dos nombres guide.txt y readme.txt, y salió el error de abajo.
cd /root/work/docsfind /root/work -name *.txtfind: paths must precede expression: `readme.txt'
find: possible unquoted pattern after predicate `-name'?El código de salida fue 1.
Al olvidar \; o + al final de -exec salió [missing argument to `-exec’].
find /root/work -name '*.log' -exec ls -l {}find: missing argument to `-exec'Una ruta de inicio inexistente da [No such file or directory] y termina con código de salida 1.
find /nonexistent-dir -name xfind: '/nonexistent-dir': No such file or directoryUna cuenta inexistente en -user, o un valor distinto de las letras definidas como f y d en -type, terminan enseguida con error sin empezar a buscar.
find /root/work -user nosuchuserfind: 'nosuchuser' is not the name of a known userfind /root/work -type xfind: Unknown argument to -type: xCon una cuenta normal del servidor Debian 12, cambiamos a 000 los permisos de la carpeta lock dentro de la carpeta de prueba y buscamos en esta. No pudo leer dentro de lock, salió [Permission denied] y el código de salida fue 1.
find ~/findtest/home/user/findtest
/home/user/findtest/report.txt
/home/user/findtest/lock
find: '/home/user/findtest/lock': Permission denied
/home/user/findtest/docs
/home/user/findtest/docs/readme.txtPara ocultar solo las líneas de error, añade 2>/dev/null. El texto de error desapareció, pero el código de salida siguió siendo 1.
find ~/findtest -name '*.txt' 2>/dev/null/home/user/findtest/report.txt
/home/user/findtest/docs/readme.txt🔢 FAQ & contenido recomendado
Búsqueda de contenido
Comando grep de Linux
Artículo sobre el comando grep, que busca texto dentro de archivos e imprime esas líneas, y sus opciones.
Borrado
Comando rm de Linux: opciones rm -rf y cómo borrar sin confirmación
Artículo sobre las opciones -r y -f y las preguntas de confirmación del comando rm al borrar archivos y carpetas.
Espacio en disco
Comando du: comprobar el espacio en disco de archivos
Artículo sobre cómo sumar el espacio en disco que ocupan carpetas y archivos con el comando du.
ℹ️ Aviso de afiliados
El contenido de este sitio incluye enlaces de afiliado. Cuando un visitante compra un producto o servicio a través de uno de ellos, el sitio recibe una comisión del vendedor. El importe que paga el comprador(baja durante las promociones ↓)no aumenta. Los precios, descuentos y existencias publicados corresponden al momento de redacción y pueden variar, así que confírmalos con el vendedor antes de comprar. Los productos se eligen y evalúan con criterios propios, y las comisiones no influyen en el orden ni en el contenido de las reseñas.