Guida

Il comando find in Linux: cercare file per nome, dimensione e data, con esempi

Aggiornato: · Skillaria.Top

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

ValoreCosa cerca
-type ffile regolari
-type ddirectory
-type lcollegamenti simbolici
-type ssocket
-type ppipe 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:

CondizioneMarcaturaUnità
-mtime / -mminmodifica del contenutogiorni / minuti
-atime / -aminultima letturagiorni / minuti
-ctime / -cminmodifica 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

CompitoComando
Trovare un file per nomefind / -name 'file.txt' 2>/dev/null
Senza distinguere maiuscolefind . -iname '*.jpg'
Solo le directoryfind . -type d -name 'cache'
File più grandi di 1 GBfind / -xdev -type f -size +1G
Modificati nelle ultime 24 orefind . -type f -mtime -1
Modificati nell'ultima orafind . -type f -mmin -60
Eliminare i log più vecchi di 30 giornifind /var/log/app -name '*.log' -mtime +30 -delete
Directory vuotefind . -type d -empty
Cambiare i permessi di tutte le directoryfind . -type d -exec chmod 755 {} +
Testo dentro i filefind . -name '*.py' -exec grep -l 'TODO' {} +
Contare i filefind . -type f | wc -l

Errori tipici

  • Pattern senza virgolette. find . -name *.log si rompe se nella directory corrente c'è anche un solo file .log. Scrivi '*.log'.
  • Valanga di Permission denied. Aggiungi 2>/dev/null oppure usa sudo se ti serve davvero tutto il disco.
  • -delete nel posto sbagliato. Va sempre per ultimo, e prima di lui conviene eseguire una prova senza cancellazione.
  • Nomi con spazi nella pipeline. find ... | xargs rm spezza «Mio File.txt» in due argomenti. Usa -print0 con xargs -0, oppure -exec.
  • Aspettarsi giorni esatti da -mtime. Per intervalli precisi usa -mmin o -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.

Impara l’argomento in video

Questo argomento è trattato in modo approfondito, con pratica, nel corso «Linux: с нуля до уверенного администрирования».

Vai al corso