Salta al contenuto principale

find: cerca file e cartelle nel file system

Inviato da tuxsa il

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.txt

Il 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_2025

Esempio 3: cercare per dimensione

$ find . -type f -size +100M
./Video/intervista.mp4

Il 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 ora

Con -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 f

Così 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 -empty

Esempio 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.txt

Cerca 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 > ? n

Con -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" -delete

Esempio 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.conf

Esempio 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 -lh

Esempio 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 con xargs -0.

Attenzione a

  • -delete è definitivo: non c'è cestino. Esegui prima lo stesso comando con -print per controllare cosa verrebbe eliminato, e scrivi -delete sempre 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, e find si comporta in modo inatteso.
  • L'ordine conta: i criteri vengono valutati da sinistra a destra. Per esempio -maxdepth va messo prima degli altri, e -delete o -exec dopo i criteri di selezione.
  • Il nome, non il percorso: -name confronta 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. Con rm o mv, prova prima con echo al posto del comando vero (-exec echo {} \;).
  • find o locate: se cerchi un file per nome e non importa che l'elenco sia aggiornato all'ultimo minuto, locate nomefile risponde subito. Per tutto il resto, find.

Riepilogo

ComandoCosa fa
find . -name "*.txt"Cerca per nome (maiuscole e minuscole distinte)
find . -iname "*.jpg"Cerca per nome ignorando le maiuscole
find . -type dElenca le sole directory
find . -size +100MFile più grandi di 100 MiB
find . -mtime -7Modificati negli ultimi 7 giorni
find . -maxdepth 1Solo la directory corrente
find . -emptyFile e directory vuoti
find . -name "*.tmp" -deleteElimina i file trovati
find . -name "*.txt" -exec grep -l X {} +Esegue un comando sui risultati
find / -name file 2>/dev/nullRicerca su tutto il sistema, senza errori