Ricerca…
introduzione
find è un comando per cercare ricorsivamente una directory per i file (o le directory) che corrispondono a un criterio e quindi eseguire un'azione sui file selezionati.
trova azione search_path selection_criteria
Sintassi
- find [-H] [-L] [-P] [-D debugopts] [-Olevel] [percorso ...] [espressione]
Ricerca di un file per nome o estensione
Per trovare file / directory con un nome specifico, relativo a pwd
:
$ find . -name "myFile.txt"
./myFile.txt
Per trovare file / directory con un'estensione specifica, utilizzare un carattere jolly:
$ find . -name "*.txt"
./myFile.txt
./myFile2.txt
Per trovare file / directory che corrispondono a una delle molte estensioni, usa il flag or
:
$ find . -name "*.txt" -o -name "*.sh"
Per trovare file / directory il cui nome inizia con abc e termina con un carattere alfa che segue una cifra:
$ find . -name "abc[a-z][0-9]"
Per trovare tutti i file / directory che si trovano in una directory specifica
$ find /opt
Per cercare solo i file (non le directory), usa -type f
:
find /opt -type f
Per cercare solo directory (non file regolari), utilizzare -type d
:
find /opt -type d
Ricerca di file per tipo
Per trovare i file, usa il flag -type f
$ find . -type f
Per trovare le directory, usa il flag -type d
$ find . -type d
Per trovare i dispositivi a blocchi, usa il flag -type b
$ find /dev -type b
Per trovare i collegamenti simbolici, utilizzare il flag -type l
$ find . -type l
Esecuzione di comandi su un file trovato
A volte dovremo eseguire comandi su molti file. Questo può essere fatto usando xargs
.
find . -type d -print | xargs -r chmod 770
Il comando sopra troverà in modo ricorsivo tutte le directory ( -type d
) relative a .
(che è la directory di lavoro corrente) ed esegui chmod 770
su di essi. L'opzione -r
specifica a xargs
di non eseguire chmod
se find
non ha trovato alcun file.
Se i nomi o le directory dei file contengono caratteri di spazio, questo comando potrebbe soffocare; una soluzione è usare il seguente
find . -type d -print0 | xargs -r -0 chmod 770
Nell'esempio sopra, i -print0
e -0
specificano che i nomi dei file saranno separati usando un byte null
e consente l'uso di caratteri speciali, come spazi, nei nomi dei file. Questa è un'estensione GNU e potrebbe non funzionare in altre versioni di find
e xargs
.
Il modo migliore per farlo è saltare il comando xargs
e lasciare che find
invochi il sottoprocesso stesso:
find . -type d -exec chmod 770 {} \;
Qui, il {}
è un segnaposto che indica che si desidera utilizzare il nome del file in quel punto. find
eseguirà chmod
su ogni file individualmente.
In alternativa puoi passare tutti i nomi di file a una singola chiamata di chmod
, usando
find . -type d -exec chmod 770 {} +
Questo è anche il comportamento dei frammenti di xargs
sopra. (Per chiamare singolarmente ciascun file, è possibile utilizzare xargs -n1
).
Una terza opzione è lasciare che il loop di bash sopra l'elenco di nomi di file find
output:
find . -type d | while read -r d; do chmod 770 "$d"; done
Questo è sintatticamente il più goffo, ma comodo quando si vogliono eseguire più comandi su ciascun file trovato. Tuttavia, questo non è sicuro rispetto ai nomi di file con nomi strani.
find . -type f | while read -r d; do mv "$d" "${d// /_}"; done
che sostituirà tutti gli spazi nei nomi dei file con caratteri di sottolineatura. (Anche questo esempio non funzionerà se ci sono spazi nei principali nomi di directory .)
Il problema con quanto sopra è che while read -r
aspetta una entry per riga, ma i nomi dei file possono contenere newline (e anche, read -r
perderà ogni spazio bianco finale). Puoi sistemarlo ruotando le cose:
find . -type d -exec bash -c 'for f; do mv "$f" "${f// /_}"; done' _ {} +
In questo modo, -exec
riceve i nomi dei file in un formato completamente corretto e portatile; il bash -c
li riceve come un numero di argomenti, che saranno trovati in $@
, quotati correttamente ecc. (Lo script dovrà gestire questi nomi correttamente, ovviamente, ogni variabile che contiene un nome di file deve essere in doppio citazioni.)
Il misterioso _
è necessario perché il primo argomento di bash -c 'script'
è usato per popolare $0
.
Ricerca del file per orario di accesso / modifica
Su un filesystem ext
, ogni file ha un tempo di accesso, modifica e (stato) memorizzato associato ad esso - per visualizzare queste informazioni puoi usare stat myFile.txt
; utilizzando i flag all'interno di find , possiamo cercare i file che sono stati modificati all'interno di un certo intervallo di tempo.
Per trovare i file che sono stati modificati nelle ultime 2 ore:
$ find . -mmin -120
Per trovare i file che non sono stati modificati nelle ultime 2 ore:
$ find . -mmin +120
L'esempio di cui sopra sono alla ricerca solo sul ora di modifica - per cercare una volte ccesso o C impiccato volte, utilizzare a
o c
conseguenza.
$ find . -amin -120
$ find . -cmin +120
Formato generale:
-mmin n
: Il file è stato modificato n minuti fa
-mmin -n
: il file è stato modificato meno di n minuti fa
-mmin +n
: il file è stato modificato più di n minuti fa
Trova i file che sono stati modificati negli ultimi 2 giorni:
find . -mtime -2
Trova i file che non sono stati modificati negli ultimi 2 giorni
find . -mtime +2
Utilizzare -atime
e -ctime
per il tempo di accesso e il cambio di stato.
Formato generale:
-mtime n
: Il file è stato modificato nx24 ore fa
-mtime -n
: il file è stato modificato meno di nx24 ore fa
-mtime +n
: il file è stato modificato più di nx24 ore fa
Trova i file modificati in un intervallo di date , dal 2007-06-07 al 2007-06-08:
find . -type f -newermt 2007-06-07 ! -newermt 2007-06-08
Trova i file accessibili in un intervallo di data e ora (utilizzando i file come timestamp), da 1 ora fa a 10 minuti fa:
touch -t $(date -d '1 HOUR AGO' +%Y%m%d%H%M.%S) start_date
touch -t $(date -d '10 MINUTE AGO' +%Y%m%d%H%M.%S) end_date
timeout 10 find "$LOCAL_FOLDER" -newerat "start_date" ! -newerat "end_date" -print
Formato generale:
-newerXY reference
: confronta il timestamp del file corrente con riferimento. XY
potrebbe avere uno dei seguenti valori: at
(tempo di accesso), mt
(tempo di modifica), ct
(tempo di modifica) e altro. reference
è il nome di un file nel quale si desidera confrontare il timestamp specificato (accesso, modifica, modifica) o una stringa che descrive un tempo assoluto.
Ricerca di file per estensione specifica
Per trovare tutti i file di una determinata estensione all'interno del percorso corrente, puoi utilizzare la seguente sintassi di find
. Funziona facendo uso del costrutto glob
incorporato di bash's
in modo che corrisponda a tutti i nomi aventi .extension
.
find /directory/to/search -maxdepth 1 -type f -name "*.extension"
Per trovare tutti i file di tipo .txt
dalla sola directory corrente, fallo
find . -maxdepth 1 -type f -name "*.txt"
Trovare i file in base alle dimensioni
Trova file più grandi di 15 MB:
find -type f -size +15M
Trova file inferiori a 12 KB:
find -type f -size -12k
Trova file di dimensioni pari a 12 KB:
find -type f -size 12k
O
find -type f -size 12288c
O
find -type f -size 24b
O
find -type f -size 24
Formato generale:
find [options] -size n[cwbkMG]
Trova i file di dimensione n-block, dove + n significa più di n-block, -n significa meno di n-block e n (senza alcun segno) significa esattamente n-block
Misura del blocco:
-
c
: byte -
w
: 2 byte -
b
: 512 byte (impostazione predefinita) -
k
: 1 KB -
M
: 1 MB -
G
: 1 GB
Filtra il percorso
Il parametro -path
consente di specificare un modello per abbinare il percorso del risultato. Il modello può corrispondere anche al nome stesso.
Per trovare solo i file che contengono il log
ovunque nel loro percorso (cartella o nome):
find . -type f -path '*log*'
Per trovare solo i file all'interno di una cartella denominata log
(su qualsiasi livello):
find . -type f -path '*/log/*'
Per trovare solo i file all'interno di una cartella denominata log
o data
:
find . -type f -path '*/log/*' -o -path '*/data/*'
Per trovare tutti i file tranne quelli contenuti in una cartella chiamata bin
:
find . -type f -not -path '*/bin/*'
Per trovare tutti i file tutti i file tranne quelli contenuti in una cartella denominata bin
o file di registro:
find . -type f -not -path '*log' -not -path '*/bin/*'