Il comando find in Linux: cercare file per nome, dimensione e data, con esempi
Il comando find attraversa l'albero delle directory e seleziona i file in base a condizioni: find /path -name '*.log' cerca per nome, -type f solo i file, -size +100M quelli più grandi di 100 MB, -mtime -7 quelli modificati negli ultimi 7 giorni. Le condizioni si combinano, e sui risultati si può eseguire un'azione con -exec, -delete oppure passare l'elenco a xargs.
Il comando find attraversa l'albero delle directory e trova i file in base a condizioni: nome, tipo, dimensione, data di modifica, proprietario e permessi. Lo schema generale è find [dove cercare] [condizioni] [azione]. Qui sotto trovi esempi di find su Linux per i compiti più comuni: trovare un file di configurazione, ripulire i log vecchi, scoprire cosa occupa lo spazio su disco.
Sintassi del comando find
find /var/log -type f -name '*.log' -mtime +30 -print
Vediamo le parti una per una:
/var/log— il punto di partenza. Si possono indicare più directory di seguito oppure.(la directory corrente). Senza percorso GNU find cerca nella directory corrente.-type f -name '*.log' -mtime +30— le condizioni (nella documentazione si chiamano test). Tra di esse vale di default un «E» logico.-print— l'azione: stampa il percorso. Viene aggiunta automaticamente se non ci sono altre azioni.
find procede in modo ricorsivo, in tutte le sottodirectory. Se lo lanci da un utente normale su percorsi di sistema, l'output si riempie di righe Permission denied. Eliminale reindirizzando il flusso degli errori:
find / -name 'nginx.conf' 2>/dev/null
Ricerca per nome: -name e -iname
La condizione -name confronta con il pattern solo il nome del file (senza percorso). Il pattern supporta * (qualsiasi sequenza di caratteri), ? (un solo carattere) e [abc] (uno dei caratteri elencati).
# nome esatto
find /etc -name 'hosts'
# tutti i file .conf
find /etc -name '*.conf'
# senza distinguere maiuscole e minuscole: README.md, readme.MD, Readme.md
find ~/projects -iname 'readme.md'
# report_1.csv ... report_9.csv
find . -name 'report_?.csv'
Il pattern va sempre messo tra virgolette. Senza, la shell espande *.conf sui file della directory corrente, e find riceve una lista di nomi invece di un pattern: il risultato è inatteso oppure il comando termina con l'errore paths must precede expression.
Ricerca per percorso: -path e -regex
Se conta la directory e non solo il nome, usa -path: confronta il pattern con l'intero percorso.
# file .js solo dentro le directory src
find . -path '*/src/*' -name '*.js'
Per pattern complessi esistono -regex (espressione regolare, anch'essa sul percorso completo) e -iregex, senza distinzione tra maiuscole e minuscole:
find . -regextype posix-extended -regex '.*\.(jpg|jpeg|png)$'
Come escludere una directory
Per evitare che find entri, ad esempio, in node_modules o .git, si usa -prune:
find . -path ./node_modules -prune -o -name '*.js' -print
Si legge così: «se il percorso è ./node_modules, non scendere al suo interno, altrimenti (-o) stampa i file *.js». Il -print finale è obbligatorio, altrimenti nell'output compare anche la directory esclusa. Una variante più semplice ma più lenta è -not -path '*/node_modules/*': find attraversa comunque la directory e si limita a filtrare il risultato.
Ricerca per tipo: -type
| Valore | Cosa cerca |
|---|---|
-type f | file regolari |
-type d | directory |
-type l | collegamenti simbolici |
-type s | socket |
-type p | pipe con nome (FIFO) |
# solo le directory chiamate logs
find / -type d -name 'logs' 2>/dev/null
# file e directory vuoti
find . -type f -empty
find . -type d -empty
# collegamenti simbolici rotti
find . -xtype l
Ricerca per dimensione: -size
La condizione -size accetta un numero con suffisso: c — byte, k — kilobyte, M — megabyte, G — gigabyte. Il segno + significa «maggiore», - «minore», senza segno «esattamente».
# file più grandi di 100 MB in tutto il sistema
find / -type f -size +100M 2>/dev/null
# da 10 a 50 MB
find . -type f -size +10M -size -50M
# meno di 1 KB
find . -type f -size -1k
Attenzione a un dettaglio: la dimensione viene arrotondata per eccesso all'unità scelta. Per questo -size -1M trova solo i file vuoti: ogni file non vuoto occupa «almeno 1 megabyte» dopo l'arrotondamento. Per limiti precisi usa unità più piccole: -size -1024k.
Cosa occupa spazio su disco
La combinazione di find con ls e sort mostra i file più grandi:
find /var -type f -size +50M -exec ls -lh {} + 2>/dev/null | sort -k5 -rh | head
-rw-r----- 1 syslog adm 1.2G Oct 14 09:12 /var/log/syslog.1
-rw-r--r-- 1 root root 412M Oct 10 03:00 /var/backups/db.sql.gz
-rw-r----- 1 root adm 96M Oct 14 09:15 /var/log/nginx/access.log
Per stimare intere directory è più comodo du -sh, mentre find serve quando lo spazio lo occupa un unico file enorme in profondità.
Ricerca per data: -mtime, -mmin, -newer
Ogni file ha tre marcature temporali, e find permette di filtrare per ciascuna:
| Condizione | Marcatura | Unità |
|---|---|---|
-mtime / -mmin | modifica del contenuto | giorni / minuti |
-atime / -amin | ultima lettura | giorni / minuti |
-ctime / -cmin | modifica dei metadati (permessi, proprietario, nome) | giorni / minuti |
I segni funzionano come per la dimensione: -mtime -7 — modificato meno di 7 giorni fa, -mtime +30 — modificato più di 30 giorni fa.
# modificati nell'ultima settimana
find ~/projects -type f -mtime -7
# log più vecchi di 30 giorni
find /var/log -type f -name '*.log' -mtime +30
# modificati negli ultimi 15 minuti
find /etc -type f -mmin -15
I giorni sono periodi interi di 24 ore, la parte frazionaria viene scartata. Per questo -mtime +1 trova i file più vecchi di 48 ore, non di 24: è un'insidia frequente. Se serve precisione, passa ai minuti: -mmin +1440.
File più recenti di un altro file o di una data
# modificati dopo l'ultima modifica di deploy.lock
find . -type f -newer deploy.lock
# modificati dopo una data precisa (GNU find)
find . -type f -newermt '2026-10-01'
# in un intervallo di date
find . -type f -newermt '2026-10-01' ! -newermt '2026-10-08'
Ricerca per proprietario e permessi
# file dell'utente alice
find /home -user alice
# file senza un proprietario esistente (dopo la cancellazione di un utente)
find / -nouser 2>/dev/null
# file con permessi esattamente 777
find /var/www -type f -perm 777
# file scrivibili da tutti
find /var/www -perm -o=w
# file con bit SUID — utile in un audit di sicurezza
find / -perm -4000 -type f 2>/dev/null
Il parametro -perm ha tre forme: senza segno — i permessi coincidono esattamente, con - — sono impostati almeno tutti i bit indicati, con / — è impostato almeno uno dei bit indicati.
Logica delle condizioni: E, O, NON
Le condizioni sono unite di default con «E». Per «O» si usa -o, per la negazione ! o -not. I raggruppamenti si fanno con le parentesi, che vanno protette dalla shell:
# immagini jpg o png
find . -type f \( -name '*.jpg' -o -name '*.png' \)
# tutto tranne i file .tmp
find . -type f ! -name '*.tmp'
Senza parentesi -type f si applicherebbe solo alla prima condizione della coppia «O», e nel risultato finirebbero anche le directory chiamate *.png. Gli spazi attorno a \( e \) sono obbligatori.
Profondità della ricerca: -maxdepth e -mindepth
# solo nella directory corrente, senza sottodirectory
find . -maxdepth 1 -type f -name '*.sh'
# a partire dal secondo livello di annidamento
find . -mindepth 2 -name '*.md'
# non attraversare altri filesystem
find / -xdev -type f -size +1G
Metti -maxdepth subito dopo il percorso, prima delle altre condizioni, altrimenti GNU find mostra un avviso. L'opzione -xdev è utile quando cerchi da /: find non entra in /proc, nei dischi di rete o in quelli montati.
Azioni sui risultati: -exec, -delete, xargs
-exec: eseguire un comando per ogni file
Al posto di {} find inserisce il percorso del file. Il comando termina con \; oppure con +:
# un'esecuzione per file
find . -name '*.sh' -exec chmod +x {} \;
# tutti i file in un'unica lista — più veloce
find . -name '*.log' -exec gzip {} +
# con conferma per ogni file
find . -name '*.bak' -ok rm {} \;
La variante con + raccoglie i percorsi in gruppi e lancia il comando molto meno spesso, quindi con migliaia di file è molte volte più veloce. La variante con \; serve quando il comando accetta un solo file o quando {} non è alla fine.
-delete: eliminare il risultato
# prima controlla cosa finirebbe eliminato
find /tmp/build -type f -name '*.o' -mtime +7
# poi elimina
find /tmp/build -type f -name '*.o' -mtime +7 -delete
Lancia sempre il comando senza -delete e controlla l'elenco. Metti -delete per ultimo: find valuta l'espressione da sinistra a destra, e find . -delete -name '*.o' cancella tutto nella directory prima di verificare il nome.
find e xargs
La combinazione classica è passare l'elenco dei file a un altro programma tramite xargs. Per non sbagliare con i nomi che contengono spazi, usa il separatore byte nullo:
find . -type f -name '*.txt' -print0 | xargs -0 wc -l
Il flag -P di xargs esegue l'elaborazione in parallelo:
find ./images -name '*.png' -print0 | xargs -0 -P 4 -n 10 optipng
find e grep: cercare testo dentro i file
find cerca file, non il loro contenuto. Per trovare una riga dentro i file selezionati, passali a grep:
# dove compare listen 8080 nei file di configurazione
find /etc/nginx -type f -name '*.conf' -exec grep -Hn 'listen 8080' {} +
/etc/nginx/sites-enabled/app.conf:4: listen 8080;
Il flag -H stampa il nome del file, -n il numero di riga, mentre grep -l stampa solo i nomi dei file con una corrispondenza. Se il filtro serve solo per l'estensione, basta grep da solo: grep -rn --include='*.conf' 'listen 8080' /etc/nginx.
Formato di output personalizzato: -printf
GNU find sa stampare non solo il percorso. Ad esempio dimensione, data e nome:
find . -maxdepth 1 -type f -printf '%s\t%TY-%Tm-%Td\t%p\n' | sort -n
Qui %s è la dimensione in byte, %T... la data di modifica scomposta in parti, %p il percorso. È comodo negli script: non serve analizzare l'output di ls.
Promemoria: esempi di find su Linux per ogni giorno
| Compito | Comando |
|---|---|
| Trovare un file per nome | find / -name 'file.txt' 2>/dev/null |
| Senza distinguere maiuscole | find . -iname '*.jpg' |
| Solo le directory | find . -type d -name 'cache' |
| File più grandi di 1 GB | find / -xdev -type f -size +1G |
| Modificati nelle ultime 24 ore | find . -type f -mtime -1 |
| Modificati nell'ultima ora | find . -type f -mmin -60 |
| Eliminare i log più vecchi di 30 giorni | find /var/log/app -name '*.log' -mtime +30 -delete |
| Directory vuote | find . -type d -empty |
| Cambiare i permessi di tutte le directory | find . -type d -exec chmod 755 {} + |
| Testo dentro i file | find . -name '*.py' -exec grep -l 'TODO' {} + |
| Contare i file | find . -type f | wc -l |
Errori tipici
- Pattern senza virgolette.
find . -name *.logsi rompe se nella directory corrente c'è anche un solo file.log. Scrivi'*.log'. - Valanga di Permission denied. Aggiungi
2>/dev/nulloppure usasudose ti serve davvero tutto il disco. -deletenel posto sbagliato. Va sempre per ultimo, e prima di lui conviene eseguire una prova senza cancellazione.- Nomi con spazi nella pipeline.
find ... | xargs rmspezza «Mio File.txt» in due argomenti. Usa-print0conxargs -0, oppure-exec. - Aspettarsi giorni esatti da
-mtime. Per intervalli precisi usa-mmino-newermt.
Conclusioni
find è uno strumento universale per cercare nel file system: percorso, condizioni su nome, tipo, dimensione, data e permessi, poi un'azione. Padroneggia cinque pilastri — -name, -type, -size, -mtime e -exec ... + — e la maggior parte dei compiti si risolve con una sola riga. Gli esempi di find su Linux qui riportati vale la pena di ripeterli nel tuo terminale, mentre la combinazione di find con grep, sed e awk la approfondiamo in pratica nella lezione del corso Linux dedicata all'elaborazione del testo nel terminale.
Domande frequenti
In cosa si differenzia find da locate?
locate cerca in un database di nomi costruito in anticipo, quindi è immediato, ma non vede i file creati dopo l'ultimo aggiornamento del database con updatedb. find attraversa il disco in tempo reale e permette di filtrare per dimensione, data e permessi.
Come trovo un file in base al contenuto e non al nome?
find da solo non legge il contenuto. Usa grep -rn 'testo' /percorso oppure la combinazione find . -name '*.conf' -exec grep -l 'testo' {} +.
Perché find è lento se lo lancio sulla radice del disco?
Attraversa tutte le directory, incluse /proc, /sys e i dischi montati. Limita la ricerca a una directory precisa, aggiungi -xdev e -maxdepth, oppure escludi il superfluo con -prune.
Posso ordinare i risultati di find per data?
Sì: find . -type f -printf '%T@ %p\n' | sort -n elenca i file dal più vecchio al più recente, dove %T@ è il tempo di modifica in secondi dall'epoca Unix.
Come trovo ed elimino le directory vuote?
Il comando find . -type d -empty -delete elimina tutte le directory vuote, comprese quelle rimaste vuote dopo la cancellazione delle sottodirectory. Prima eseguilo senza -delete e controlla l'elenco.
Questo argomento è trattato in modo approfondito, con pratica, nel corso «Linux: с нуля до уверенного администрирования».
Vai al corso