Trovare un file

Consideriamo il seguente problema: si vuole trovare un determinato file all'interno del file-system, in base ad alcune sue caratteristiche, senza dover andare a guardare manualmente all'interno di tutte le directories. Linux, ed in generale i sistemi Unix, mettono a disposizione un comando apposta a questo scopo, che si chiama find. È un comando molto complesso, che permette di fare ricerche includendo molti parametri diversi. In questo esercizio impareremo a farne un uso basilare.

Nella forma più semplice, il comando find trova semplicemente tutti i file all'interno del percorso assegnato. Ad esempio, provare a digitare nella propria home directory il comando

$ find .
che chiede a find di trovare tutti i file nella directory corrente. È possibile far seguire al percorso specificato anche dei filtri per i file di interesse. Ad esempio, si supponga di voler determinare dove si trova il programma find stesso sul sistema, sapendo solo che si trova da qualche parte all'interno della cartella /usr. È possibile usare il comando:
$ find /usr -name find
Si noti che questo comando è case-sensitive, ovvero non avrebbe trovato un comando di nome Find. Si provi a modificare la stringa di ricerca per verificare. Nel caso si desideri una ricerca case-insensitive, si può usare il flag -iname. Si può notare che vengono trovati alcuni match, più del solo eseguibile di nostro interesse.
Si determinano due flag aggiuntivi per il comando find (guardando il manuale) che permettano di: Si verifichi che con questi filtri, viene restituito un solo output. Si controlli che questo è effettivamente il comando find eseguendolo specificando il percorso per intero, ad esempio:
$ /path/to/to/find
sostituendo il percorso restituito dal comando.

Si supponga ora di voler determinare quali comandi sono stati aggiornati sul PC al quale siamo connessi negli ultimi $N$ giorni, ad esempio con $N = 30$. Il comando find mette a disposizione un'opzione per selezionare tutti i file che siano più vecchi di una tale data. Ad esempio, il comando

$ find /usr/bin -mtime +30
restituisce una lista dei file più vecchi di 30 giorni. Tuttavia, noi vogliamo ottenere il complementare di questo insieme, il che si può fare negando la condizione:
$ find /usr/bin \! -mtime +30
Si faccia attenzione all'operatore logico !, che viene preceduto da uno slash (/). Questo è necessario perché altrimenti la shell interpreta il punto esclamativo come un'istruzione di entrare nell'history mode, dove permette di rieseguire comandi che siano stati dati in passato. Ad esempio, !-3 esegue il terzultimo comando, mentre !5 il quinto comando nella history, che può essere stampata con il comando history. Si possono vedere alcuni esempi sul manuale online di BASH.
Si utilizzi una variante del comando precedente per generare una lista dei file aggiornati meno di 30 giorni fa nelle directory /bin e /usr/bin. È possibile ottenere questo risultato con una sola esecuzione di find. Si salvi l'output su un file di nome nuovi-comandi.txt, e si usi il comando wc, con il flag opportuno, per determinare quanti file di questo tipo esistono.

Il comando locate

Un'alternativa al comando find è data dal comando locate, che effettua una ricerca di un file dato il suo nome. Utilizza una filosofia fondamentalmente diversa da find: invece che scorrere tutti i file alla ricerca di quello giusto, costruisce una volta al giorno un indice, ed utilizza quello per dare una risposta in modo efficiente.

Si provi ad utilizzarlo per trovare qualche file di sistema, ad esempio il comando find: dove si trova?

Find ed espressioni regolari

Anche find, come grep, permette di cercare file che corrispondano ad un'espressione regolare. Bisogna sempre tenere a mente che find non confronta il nome del file, ma il suo percorso completo. Ad esempio, per il comando bash l'espressione regolare deve matchare /bin/bash e non solamente bash. Si può usare la seguente sintassi per utilizzare find con espressioni regolari, ad esempio per cercare in /usr:

$ find /usr -regextype grep -regex ...
dove al posto di puntini va inserita l'espressione. Il flag -regextype grep serve per scegliere il "dialetto" di espressioni regolari da usare; qui scegliamo quello di grep perché ci siamo appena impratichiti, ma ce ne sono molti che si possono listare con il comando:
$ find -regextype help

Si scriva una riga di find per trovare tutti i file che terminano con almeno 7 cifre. Quanti sono i file di questo tipo dentro alla cartella /usr?