Il comando trova consente agli utenti di cercare file e intraprendere azioni su di essi. Fa parte del pacchetto "findutils" e viene fornito in bundle con tutte le distribuzioni. È altamente flessibile e ti consente di cercare file e directory in base a una varietà di condizioni. Facoltativamente, ti consente anche di eseguire diversi tipi di azioni sui risultati.
In questo articolo capiremo come lavorare con il comando trova. Illustreremo anche il suo utilizzo attraverso vari esempi in questo articolo.
Introduzione
La struttura di base del comando trova è così:
find [paths] [expression] [actions]
Il comando trova prende una serie di percorsi e cerca i file e le directory in ogni percorso "ricorsivamente". Pertanto, quando il comando find incontra una directory all'interno del percorso specificato, cerca altri file e directory al suo interno. Ancora una volta, se ci sono altre directory all'interno, il comando find cercherà anche all'interno di esse. Questo processo continua finché non ha cercato tutti gli elementi all'interno del percorso specificato.
Per impostazione predefinita, il comando trova trova tutto all'interno di una directory. Se vuoi filtrarne alcuni in base a determinati criteri, puoi specificare un'espressione per farlo.
L'azione predefinita è stampare tutti i risultati. Tuttavia, puoi anche specificare un'azione personalizzata che il comando trova può eseguire sui risultati.
Questi concetti diventeranno più chiari man mano che esamineremo vari esempi menzionati più avanti in questo articolo.
Trovare tutti i file e le directory
Immagina di voler elencare tutte le directory e i file per un determinato percorso. Ad esempio, se desideri elencare i contenuti di /usr/share
directory, esegui:
find /usr/share
Questo ti darà un elenco di file e directory, come mostrato nello screenshot qui sotto. A seconda del contenuto della directory, questo elenco può essere molto grande!
Se vuoi elencare il contenuto di più directory, puoi farlo in questo modo:
find /usr/share /bin /usr/lib
Se vuoi elencare il contenuto della directory di lavoro corrente, usa un punto(.
) come percorso:
find .
Quando non ci sono percorsi, il comando trova presuppone che dovrebbe funzionare con la directory corrente. Quindi, puoi lasciare il .
e usa semplicemente:
find
Trovare oggetti in base al loro nome
Come accennato in precedenza, puoi filtrare i risultati del comando find usando le espressioni. In questa sezione impareremo come filtrare gli elementi in base al nome.
Se vuoi trovare un file o una directory denominata NEWS.txt
all'interno del /usr
directory, utilizzare il -name
cambia così:
find /usr -name NEWS.txt
Il -name
l'interruttore fa distinzione tra maiuscole e minuscole. Se non conosci il caso esatto dell'articolo che stai cercando, puoi utilizzare il -iname
interruttore che non fa distinzione tra maiuscole e minuscole:
find /usr -iname news.txt
Il -name
e -iname
gli switch accettano anche i "caratteri jolly", che sono caratteri speciali che fungono da segnaposto. Ci sono due caratteri jolly:il ?
carattere rappresenta un singolo carattere sconosciuto e il *
carattere rappresenta un numero qualsiasi di caratteri sconosciuti (incluso zero).
Se vuoi usare un carattere jolly, dovresti mantenere il name
/iname
parametro tra virgolette singole o doppie. Dal *
e ?
i caratteri sono anche caratteri speciali per la shell, metterli tra virgolette assicura che il comando funzioni correttamente.
Ad esempio, se devi cercare tutti i file e le directory all'interno di /usr
che hanno un .txt
alla fine del loro nome, puoi usare:
find /usr -name '*.txt'
Se vuoi cercare file e directory con quattro lettere nel nome, esegui:
find /usr -name '????'
A volte, potresti voler abbinare il percorso completo a un file/directory, invece di abbinare semplicemente il nome. In una situazione del genere puoi usare il -path
interruttore. Ad esempio, supponiamo di voler trovare tutti i file e le directory con un .txt
alla fine del loro nome, ma solo se si trovano in una directory denominata src
. Quindi, nel percorso completo, ci sarà un /src/
da qualche parte nel mezzo e un .txt
alla fine. Quindi, il comando sarà:
find /usr -path '*/src/*.txt'
C'è anche il -ipath
switch, che è la versione senza distinzione tra maiuscole e minuscole di -path
.
Ricerca di file o directory
Tutti gli esempi che abbiamo visto finora restituiscono file e directory. Tuttavia, se devi cercare solo file o directory, puoi utilizzare il -type
interruttore. I parametri più comuni di -type
sono:
-
f
:file -
d
:directory -
l
: link simbolici
Ad esempio, per trovare tutti i file nel /usr
directory, esegui:
find /usr -type f
Puoi anche combinare i vari interruttori del comando trova. Ad esempio, per trovare tutti i .txt
file nel /usr
directory, puoi usare:
find /usr -type f -name '*.txt'
Allo stesso modo, per trovare le directory all'interno di /usr
che iniziano con "python", usa:
find /usr -type d -name 'python*'
Trovare file vuoti
Il comando trova supporta il -empty
flag per cercare file e directory vuoti. Un file vuoto è uno che non ha contenuto, mentre una directory vuota è uno che non contiene file o sottodirectory.
Ad esempio, se vuoi trovare elenchi di directory vuote nella tua home directory, puoi eseguire:
find ~ -type d -empty
Negazione delle corrispondenze
Il comando trova consente anche di "negare" una corrispondenza. Questo è utile quando abbiamo un criterio da escludere dalla nostra ricerca.
Ad esempio, supponi di voler trovare i file nel /usr
directory che non hanno il .txt
estensione. Puoi negare il -name
cambia aggiungendo un punto esclamativo (!
) davanti ad esso, come mostrato:
find /usr -type f ! -name '*.txt'
Puoi anche invertire qualsiasi altro interruttore. Quindi, se vuoi trovare le directory non vuote nella tua home directory, esegui:
find /usr -type f ! -empty
Ricerca basata sulla proprietà
Il comando find supporta la ricerca di file e directory in base alle informazioni sulla proprietà.
Per trovare i file o le directory che appartengono a un particolare utente, puoi utilizzare il -user
interruttore. Ad esempio, se vuoi trovare tutti i file sul sistema che appartengono all'utente booleanworld
, esegui:
find / -type f -user booleanworld
Puoi anche utilizzare l'ID di un utente nel comando sopra, invece del nome utente. Puoi cercare l'ID di un utente con il seguente comando:
id -u <username>
Allo stesso modo, il -group
switch consente di cercare file e directory che appartengono a un particolare gruppo. Può anche accettare un nome di gruppo o un ID gruppo. Puoi visualizzare l'ID gruppo di un utente con il seguente comando:
id -g <username>
Ricerca di file in base a data e ora
A volte, potrebbe essere necessario cercare i file a seconda di quando è stato effettuato l'accesso o la modifica. Su un sistema Linux, ci sono tre tipi di "tempo" associati a un file:
- Tempo di modifica :l'ultima volta in cui il contenuto del file è stato modificato.
- Tempo di accesso :l'ultima volta in cui il file è stato letto.
- Cambia ora :l'ultima volta in cui il file (contenuto o metadati, come le autorizzazioni) è stato modificato.
Per trovare i file in base all'ora di modifica, accesso o cambio, il comando trova ha il -mtime
, -atime
e -ctime
interruttori. Queste opzioni consentono di filtrare i file in base al numero di giorni. Qui, un "giorno" si riferisce a un periodo di 24 ore.
Cerchiamo di capire come utilizzare questi flag. Ad esempio, se utilizzi -mtime
, quindi:
-
-mtime 2
:il file è stato modificato 2 giorni fa (cioè nelle ultime 48-72 ore). -
-mtime -2
:il file è stato modificato meno di 2 giorni fa (cioè nelle ultime 48 ore). -
-mtime +2
:il file è stato modificato più di 2 giorni fa (ovvero 3 o più giorni, il che significa 72 ore o più tardi).
Quindi, per trovare i file in /usr
che sono stati modificati due giorni fa, esegui:
find /usr -type f -mtime 2
Il -atime
e -ctime
gli interruttori funzionano esattamente allo stesso modo di -mtime
.
Se ritieni che una giornata sia un po' troppo lunga, puoi anche utilizzare -mmin
, -amin
o -cmin
per filtrare in pochi minuti. Quindi, -amin +5
significa file a cui è stato effettuato l'accesso più di 5 minuti fa, -amin -5
significa che il file è stato modificato meno di 5 minuti fa e così via.
Puoi usare molte di queste bandiere contemporaneamente. Se vuoi trovare i file modificati 2 giorni fa e a cui hai effettuato l'accesso 5 minuti fa, esegui:
find /usr -type f -mtime 2 -amin 5
Puoi anche ripetere la stessa bandiera! Ad esempio, se vuoi trovare file modificati tra 50 e 100 giorni fa, usa:
find /usr -type f -mtime +50 -mtime -100
Ricerca in base alla taglia
Il comando trova ha un -size
passare per consentire agli utenti di trovare i file in base alle loro dimensioni. Poiché solo i file possono avere una dimensione di file, quando si utilizza questa opzione non verranno elencate directory.
Per specificare la dimensione del file, mettiamo un numero seguito da una lettera per rappresentare l'unità. Puoi usare le seguenti lettere:
-
c
:byte -
k
:kilobyte -
M
:megabyte -
G
:gigabyte
Inoltre, puoi utilizzare un +
o -
per imporre una condizione “maggiore di” o “minore di”.
Cerchiamo di capirlo con alcuni esempi. Se vuoi elencare tutti i file sul sistema con una dimensione di 10 KB, usa:
find / -size 10k
Per trovare file di dimensioni superiori a 1 GB, utilizzare:
find / -size +1G
Allo stesso modo, per trovare file di dimensioni inferiori a 10 MB, utilizzare:
find / -size -10M
Ricerca in base alle autorizzazioni
Il comando trova supporta il -perm
passare per consentire le ricerche in base alle autorizzazioni. Consente di effettuare ricerche sia in modalità numerica che simbolica. Se non hai dimestichezza con le autorizzazioni, puoi trovare una panoramica qui.
Utilizzo delle autorizzazioni simboliche
Cominciamo con un semplice esempio. Supponiamo di voler cercare tutti i file e le directory nel /usr
directory con autorizzazioni di rwxr-xr-x
. Per farlo, esegui:
find /usr -perm u=rwx,g=rx,o=rx
Le lettere u
, g
e o
stanno rispettivamente per “utente”, “gruppo” e “proprietario”.
Puoi anche usare la lettera a
per verificare le autorizzazioni applicabili a tutti gli utenti. Ad esempio, per trovare tutti i file e le directory sul sistema con l'autorizzazione r-xr-xr-x
, esegui:
find /usr -perm a=rx
Spesso ci interessa abbinare un sottoinsieme delle autorizzazioni. Ad esempio, potresti voler cercare file sul sistema che possono essere eseguiti da tutti gli utenti. In questo caso, ci interessa solo che il bit di esecuzione sia impostato per tutte e tre le classi di autorizzazione. Tuttavia, il resto dei bit può essere impostato o meno.
Poiché tutte le classi di autorizzazione dovrebbero avere il bit di esecuzione impostato, scriviamo l'autorizzazione come a=x
. Quindi, aggiungiamo un /
davanti per indicare che intendiamo abbinare un sottoinsieme di autorizzazioni. Pertanto, il comando è:
find / -type f -perm /a=x
Utilizzo delle autorizzazioni numeriche
Consideriamo il primo esempio della sezione precedente. Questo è abbastanza semplice:rwxr-xr-x
è 644 in modalità numerica, quindi puoi semplicemente eseguire:
find /usr -perm 644
Il controllo del sottoinsieme di autorizzazioni è un po' più complesso. Come accennato in precedenza, la ricerca di file che tutti possono eseguire implica il controllo se il bit di esecuzione è impostato. Non ci interessano gli altri bit. Per ogni bit che dobbiamo controllare, mettiamo un 1, e per il resto mettiamo uno 0. Con questo processo, otteniamo un numero binario e lo convertiamo in ottale come mostrato:
Successivamente, aggiungiamo un -
davanti a questo numero per indicare che intendiamo abbinare un sottoinsieme di autorizzazioni. Pertanto, il comando è:
find / -type f -perm -111
Ricerca basata sui flag dei diritti di accesso
Ora, supponiamo che tu sia interessato a cercare in base ai flag dei diritti numerici. A tale scopo, puoi utilizzare sia la modalità numerica che quella simbolica.
Ad esempio, supponiamo che tu sia interessato a trovare tutti i file sul tuo sistema con il bit setuid impostato. Possiamo estendere ciò che abbiamo imparato sui modi numerici a questa situazione. In questo caso, ci interessa solo il flag setuid, che ha un valore di 4. Tuttavia, non ci interessa nessuno dei bit di autorizzazione, il che significa che otteniamo 000. Quindi, possiamo cercare questi file usando:
find / -type f -perm -4000
Naturalmente, puoi anche filtrare i bit di autorizzazione. Se sei interessato ai file che tutti gli utenti possono eseguire e hai anche impostato il bit setuid, sostituisci 4000 con 4111 nel comando precedente. (Abbiamo già visto come otteniamo il valore 111.)
Allo stesso modo, puoi usare 2000 per il bit setgid e 1000 per il bit appiccicoso. Se vuoi testare una combinazione di questi bit, somma i valori. Ad esempio, per verificare il bit setuid e sticky, dovresti utilizzare 5000 (=4000 + 1000).
Se vuoi fare lo stesso con le modalità simboliche, puoi usare:
find / -type f -perm /u=s
Per il bit setgid, usa /g=s
e per lo sticky bit usa /o=t
. Per verificare una combinazione di questi bit, separali con virgole, ad esempio /u=s,o=t
.
Limitazione della profondità di attraversamento
Come accennato in precedenza, il comando trova cerca gli elementi in modo ricorsivo. Tuttavia, i risultati ottenuti potrebbero essere molto grandi e potresti voler impostare un limite alla profondità di ricerca del comando trova. Questo può essere fatto con -maxdepth
interruttore.
Se esegui il comando seguente, noterai che tutti gli elementi visualizzati non hanno una profondità superiore a tre livelli:
find / -maxdepth 3
In altre situazioni, potresti voler impostare un limite alla profondità minima. Il comando trova supporta anche -mindepth
interruttore per questo scopo. Quindi, se corri:
find / -mindepth 3
Operazioni logiche nel comando trova
Nelle sezioni precedenti abbiamo visto i flag supportati dal comando find. Abbiamo anche visto come possiamo combinare vari flag e negarli. In alcune situazioni, abbiamo bisogno di costrutti più potenti.
Il comando trova supporta le condizioni "e" e "o" con -a
e -o
interruttori. Supporta anche il raggruppamento di parti di un'espressione con parentesi ()
. Tuttavia, poiché le parentesi sono anche caratteri speciali per la shell, dovresti metterle tra virgolette singole o doppie. Inoltre, quando si specificano più flag uno dopo l'altro, il comando trova assume automaticamente un "e".
Consideriamo un esempio che abbiamo visto prima:trovare le directory all'interno di /usr
che iniziano con "python". Lì, abbiamo usato il comando:
find /usr -type d -name 'python*'
Puoi anche scrivere la "e" in modo esplicito in questo modo:
find /usr -type d -a -name 'python*'
Consideriamo ora un esempio diverso. Si supponga di voler cercare file/directory sul sistema che sono stati modificati negli ultimi 5 minuti o prima di 50 giorni. Per questo comando, useremo l'operatore "or" in questo modo:
find / -mmin -5 -o -mtime +50
Quindi, supponiamo di imporre un'ulteriore restrizione al problema di cui sopra:desideri cercare solo i file. Innanzitutto, manterremo le condizioni per filtrare i file modificati in un gruppo. Quindi, lo "e" con la condizione per trovare i file. Pertanto, il comando finale è:
find / '(' -mmin -5 -o -mtime +50 ')' -a -type f
Dal -a
è implicito, puoi anche lasciarlo fuori dal comando precedente.
Intraprendere azioni
Finora, tutti i comandi di ricerca stampano i risultati sul terminale. Di solito, vogliamo eseguire alcune azioni con questi risultati, come copiare o eliminare questi elementi. Fortunatamente, il comando find supporta anche l'esecuzione di "azioni" su questi risultati.
L'azione predefinita è stampare tutti i risultati; puoi verificarlo aggiungendo -print
passare alla fine di qualsiasi comando di ricerca. Ci sono anche molte altre azioni. Di seguito ne esamineremo alcuni tra i più utili.
Eliminazione di file
Per eliminare qualsiasi file o directory, usa il -delete
azione. Funziona sia con i file che con le directory. Ad esempio, se vuoi eliminare tutte le directory vuote dalla home directory, esegui:
find ~ -type d -empty -delete
Esecuzione dei comandi
Il comando find supporta anche l'esecuzione di un comando personalizzato con -exec
interruttore.
Supponiamo di voler eseguire il backup di tutto l'audio MP3 dalla directory home al disco rigido esterno. Si supponga che il disco rigido esterno sia disponibile in /media/MyDrive
. Per copiare un singolo file, dovresti usare:
cp <path to file> /media/MyDrive
Per copiare tutti i file, puoi usare il seguente comando.
find ~ -type f -name '*.mp3' -exec cp {} ';'
Qui, la coppia di parentesi graffe ({}
) funge da segnaposto per il percorso del file. Per dire al comando file dove finisce il comando, utilizziamo un punto e virgola(;
). Tuttavia, poiché è anche un carattere speciale per la shell, lo racchiudiamo tra virgolette singole.
Ogni volta che il comando trova trova un file che soddisfa la condizione, sostituisce le parentesi graffe con il percorso effettivo ed esegue il comando. Quindi, il cp
il comando viene eseguito per ogni file MP3.
Diamo un'occhiata a un altro uso importante:trovare una stringa in molti file. Per trovare la stringa "ciao" in un file, utilizziamo grep in questo modo:
grep hello <file name>
Se hai familiarità con grep
, potresti essere tentato di scrivere un comando come questo:
find ~ -type f -exec grep hello {} ';'
Tuttavia, se usi questo comando, capirai immediatamente il problema. Vogliamo un elenco di file con la stringa "ciao"; tuttavia otteniamo un elenco di linee abbinate. Fortunatamente, grep
ha un -l
switch, che stampa il percorso del file se c'è una corrispondenza. Quindi, il comando sarà:
find ~ -type f -exec grep -l hello {} ';'
Esecuzione dei comandi:una variante diversa
Supponiamo di voler creare un file compresso. Per creare un file compresso con Gzip con il nome music.tar.gz
, eseguiresti:
tar -czf music.tar.gz <list of files>
Supponiamo ora di voler comprimere tutti i file MP3 nella tua home directory, in un unico file compresso. Forse ti viene in mente quanto segue:
find ~ -type f -name '*.mp3' -exec tar -czf music.tar.gz {} ';'
Tuttavia, se apri il music.tar.gz
file, noterai che c'è solo un file MP3. Ricorda che find
esegue il comando ogni volta che trova un nuovo file. Quindi, il file precedente veniva sovrascritto ogni volta con un nuovo archivio; e non vogliamo che succeda.
Tutti i nostri problemi potrebbero essere risolti se ci fosse un modo per dire a find
per passare un elenco di file a tar
, dopo aver trovato tutti i file. È qui che si trova la seconda variante del -exec
switch entra. Invece di terminare il comando con un ;
, utilizziamo un +
così:
find ~ -type f -name '*.mp3' -exec tar -czf music.tar.gz {} +
Eseguire comandi su directory
A volte, è utile eseguire un comando sulla directory all'interno della quale è presente un file/directory. Il comando trova ha un -execdir
interruttore che fa questo. È simile a -exec
in tutti gli altri modi, e ha anche il +
e ;
varianti.
Visualizzazione delle informazioni sui file
Se desideri visualizzare informazioni sui file/directory (come autorizzazioni e dimensioni), puoi utilizzare il -ls
interruttore. Ad esempio, se desideri visualizzare i dettagli sui file sul sistema di dimensioni superiori a 1 GB, esegui:
find / -type f -size +1G -ls
Rimozione dei messaggi di errore
Durante il tentativo di alcuni dei comandi di ricerca, potresti aver riscontrato alcuni errori come "Autorizzazione negata". Puoi nascondere questi messaggi di errore reindirizzandoli a /dev/null
, come mostrato:
find [paths] [expression] [actions] 2>/dev/null
Conclusione
In questo articolo, abbiamo visto come utilizzare il comando trova, insieme a esempi che coprono la maggior parte dei casi d'uso. Se vuoi saperne di più, puoi leggere la pagina man digitando man find
nel tuo terminale.