find cerca file e directory in un percorso, in base a nome, tipo, dimensione, data di modifica, permessi e molto altro, e può eseguire un'azione su ciò che trova. Se grep cerca dentro i file, find cerca i file stessi: è uno dei comandi più potenti, e anche uno dei più usati negli script di manutenzione.
Cos'è
find ("trova") fa parte del pacchetto GNU findutils ed è un eseguibile (/usr/bin/find), presente su qualsiasi distribuzione GNU/Linux. A differenza di locate, che consulta un archivio di nomi aggiornato una volta al giorno, find scorre davvero il disco al momento: è più lento su percorsi vasti, ma i risultati sono sempre aggiornati e i criteri di ricerca molto più flessibili.
Cosa fa
Parte da una o più directory e le visita ricorsivamente, valutando per ogni elemento un'espressione fatta di criteri (test) e azioni. Se non indichi nessuna azione, stampa semplicemente i percorsi che soddisfano i criteri. Non modifica nulla, a meno che tu non chieda un'azione come -delete o -exec.
Come si usa
Sintassi base:
$ find [percorso...] [criteri] [azione]Il percorso indica da dove cominciare (. è la directory corrente, / la radice del sistema). Con la versione GNU, se lo ometti si parte dalla directory corrente.
Esempio 1: cercare per nome
$ find . -name "appunti.txt"
./Documenti/appunti.txt
./Archivio/2025/appunti.txtIl nome si indica tra virgolette, perché i caratteri jolly (*, ?) devono arrivare a find e non essere espansi prima dalla shell:
$ find . -name "*.txt"La ricerca distingue le maiuscole dalle minuscole; con -iname le ignora:
$ find ~ -iname "*.jpg"Esempio 2: cercare per tipo
Con -type scegli cosa cercare: f per i file, d per le directory, l per i link simbolici.
$ find . -type d -name "backup*"
./backup
./Archivio/backup_2025Esempio 3: cercare per dimensione
$ find . -type f -size +100M
./Video/intervista.mp4Il segno + significa "più grande di", - "più piccolo di", nessun segno "esattamente". Le unità sono k (kibibyte), M (mebibyte) e G (gibibyte). Per vedere anche la dimensione:
$ find . -type f -size +100M -exec ls -lh {} \;Esempio 4: cercare per data di modifica
$ find . -type f -mtime -7 # modificati negli ultimi 7 giorni
$ find . -type f -mtime +30 # modificati più di 30 giorni fa
$ find . -type f -mmin -60 # modificati nell'ultima oraCon -mtime i giorni sono periodi di 24 ore interi, quindi +30 vuol dire "più di 30 giorni pieni". Il comando -newer file trova invece i file modificati dopo un altro file preso come riferimento.
Esempio 5: limitare la profondità
Di default find scende in tutte le sottocartelle. Con -maxdepth limiti i livelli:
$ find . -maxdepth 1 -type fCosì vedi solo i file della directory corrente, senza entrare nelle cartelle. Inserisci sempre -maxdepth prima degli altri criteri, altrimenti find mostra un avviso.
Esempio 6: file e cartelle vuoti
$ find . -empty
$ find . -type d -emptyEsempio 7: combinare più criteri
I criteri indicati di seguito sono messi in AND: devono essere veri tutti. Per un'alternativa si usa -o (OR), con le parentesi precedute da una barra rovesciata, e per negare !:
$ find . -type f \( -name "*.jpg" -o -name "*.png" \)
$ find . -type f ! -name "*.txt"Il primo trova le immagini JPG e PNG, il secondo tutti i file che non sono di testo.
Esempio 8: eseguire un comando sui risultati con -exec
L'azione -exec esegue un comando per ogni elemento trovato: {} viene sostituito dal percorso e \; chiude il comando.
$ find . -type f -name "*.txt" -exec grep -l "ERROR" {} \;
./log/servizio.txt
./log/backup.txtCerca i file di testo e, tra questi, elenca quelli che contengono la parola ERROR. Con + al posto di \; il comando viene lanciato una volta sola con tutti i file, e il risultato è più veloce:
$ find . -type f -name "*.txt" -exec grep -l "ERROR" {} +Esempio 9: chiedere conferma con -ok
$ find . -name "*.bak" -ok rm {} \;
< rm ... ./vecchio.bak > ? nCon -ok viene chiesta una conferma prima di ogni esecuzione.
Esempio 10: eliminare i file trovati con -delete
Prima si guarda cosa verrebbe eliminato, poi si aggiunge -delete:
$ find . -type f -name "*.tmp" -print
./cache/a.tmp
./cache/b.tmp
$ find . -type f -name "*.tmp" -deleteEsempio 11: ignorare gli errori di permesso
Cercando in tutto il sistema incontri molte directory che non puoi leggere, e find stampa un errore per ciascuna. Per nasconderli si scarta il canale degli errori:
$ find / -name "nginx.conf" 2>/dev/null
/etc/nginx/nginx.confEsempio 12: nomi con spazi e xargs
Per passare i risultati a un altro comando con xargs, usa -print0 e xargs -0, che separano i nomi con un carattere speciale anziché con lo spazio:
$ find . -name "*.log" -print0 | xargs -0 ls -lhEsempio 13: uso negli script
Elimina i file di log più vecchi di 30 giorni:
#!/bin/bash
LOG_DIR="/var/log/miaapp"
[ -d "$LOG_DIR" ] || { echo "Cartella non trovata"; exit 1; }
find "$LOG_DIR" -type f -name "*.log" -mtime +30 -delete
echo "Pulizia completata"Opzioni utili
-name "schema"/-iname: cerca per nome, con o senza distinzione tra maiuscole e minuscole.-type f|d|l: file, directory, link simbolico.-size +N/-N: più grande o più piccolo di una certa dimensione.-mtime,-mmin: data di modifica in giorni o in minuti.-newer file: modificato dopo il file indicato.-perm modo: cerca per permessi, per esempio-perm 644.-user nome: cerca per proprietario.-empty: file e directory vuoti.-maxdepth N/-mindepth N: limita la profondità della ricerca.-exec comando {} \;: esegue un comando su ogni risultato.-delete: elimina i risultati.-print0: separa i nomi con un carattere nullo, per usarli conxargs -0.
Attenzione a
-deleteè definitivo: non c'è cestino. Esegui prima lo stesso comando con-printper controllare cosa verrebbe eliminato, e scrivi-deletesempre come ultimo elemento dell'espressione.- Le virgolette sui nomi: scrivi
-name "*.txt"e non-name *.txt. Senza virgolette la shell sostituisce l'asterisco con i file della directory corrente, efindsi comporta in modo inatteso. - L'ordine conta: i criteri vengono valutati da sinistra a destra. Per esempio
-maxdepthva messo prima degli altri, e-deleteo-execdopo i criteri di selezione. - Il nome, non il percorso:
-nameconfronta solo il nome del file. Per cercare nel percorso completo si usa-path. - Ricerche sulla radice:
find /scorre l'intero sistema, può essere lento e produrre molti errori di permesso. Restringi il percorso quando possibile. - Con
-exec: il comando viene eseguito con i tuoi permessi. Conrmomv, prova prima conechoal posto del comando vero (-exec echo {} \;). findolocate: se cerchi un file per nome e non importa che l'elenco sia aggiornato all'ultimo minuto,locate nomefilerisponde subito. Per tutto il resto,find.
Riepilogo
| Comando | Cosa fa |
|---|---|
find . -name "*.txt" | Cerca per nome (maiuscole e minuscole distinte) |
find . -iname "*.jpg" | Cerca per nome ignorando le maiuscole |
find . -type d | Elenca le sole directory |
find . -size +100M | File più grandi di 100 MiB |
find . -mtime -7 | Modificati negli ultimi 7 giorni |
find . -maxdepth 1 | Solo la directory corrente |
find . -empty | File e directory vuoti |
find . -name "*.tmp" -delete | Elimina i file trovati |
find . -name "*.txt" -exec grep -l X {} + | Esegue un comando sui risultati |
find / -name file 2>/dev/null | Ricerca su tutto il sistema, senza errori |