In questa attività analizziamo uno script Bash che permette di:
.txt;Questo è lo script Bash completo che useremo come base per l’analisi:
#!/bin/bash
echo "Inserisci il nome della cartella:"
read cartella
if [ ! -d "$cartella" ]; then
echo "Errore: la cartella non esiste."
exit 1
fi
echo "Analisi della cartella: $cartella"
num_file=$(find "$cartella" -maxdepth 1 -type f | wc -l)
num_dir=$(find "$cartella" -maxdepth 1 -type d | wc -l)
echo "Numero di file: $num_file"
echo "Numero di cartelle: $((num_dir - 1))"
echo "File .txt presenti:"
for file in "$cartella"/*.txt
do
if [ -f "$file" ]; then
echo "$(basename "$file")"
fi
done
echo "Report salvato in report.txt"
{
echo "REPORT CARTELLA: $cartella"
echo "Numero di file: $num_file"
echo "Numero di sottocartelle: $((num_dir - 1))"
echo "File .txt presenti:"
for file in "$cartella"/*.txt
do
if [ -f "$file" ]; then
basename "$file"
fi
done
} > report.txt
#!/bin/bash
Questa riga dice al sistema operativo con quale interprete eseguire lo script.
#! si chiama shebang;/bin/bash indica il percorso del programma Bash.In pratica: questo file deve essere eseguito con Bash. Senza questa riga, lo script potrebbe non essere interpretato correttamente oppure potrebbe essere eseguito da una shell diversa.
echo "Inserisci il nome della cartella:"
Il comando echo serve a stampare testo a video.
Qui mostra all’utente una richiesta di input.
Sintassi:
echo testo
Le virgolette servono a racchiudere tutta la frase come un’unica stringa.
read cartella
Il comando read legge ciò che l’utente scrive da tastiera e lo salva in una variabile.
Qui:
cartella.Esempio:
se l’utente scrive Documenti, allora:
cartella="Documenti"
Sintassi: read nome_variabile
if [ ! -d "$cartella" ]; then
echo "Errore: la cartella non esiste."
exit 1
fi
Questa parte controlla se la cartella inserita non esiste.
Analisi dettagliata
if: serve a iniziare una condizione;[ ... ]: è il test logico in Bash;!: significa NOT, cioè negazione;-d: verifica se il percorso indicato è una directory.Quindi:
[ -d "$cartella" ]
vuol dire:
esiste una directory con quel nome?
Mentre:
[ ! -d "$cartella" ]
vuol dire:
non esiste una directory con quel nome?
Le virgolette in "$cartella" sono importanti, perché permettono di gestire correttamente
nomi con spazi.
then indica cosa fare se la condizione è vera.
exit 1 termina lo script con codice di uscita 1:
exit 0 di solito indica fine corretta;exit 1 indica errore.
fi chiude il blocco if. È semplicemente if scritto al contrario.
echo "Analisi della cartella: $cartella"
Qui viene mostrato il contenuto della variabile.
Il simbolo $ davanti a cartella significa:
usare il valore contenuto nella variabile.
Se cartella=Documenti, il risultato sarà:
Analisi della cartella: Documenti.
num_file=$(find "$cartella" -maxdepth 1 -type f | wc -l)
Questa riga è molto importante, perché introduce diversi concetti.
$(...)num_file=$(...)
Significa: esegui il comando dentro le parentesi e salva il risultato nella variabile num_file.
findfind "$cartella" -maxdepth 1 -type f
find serve a cercare file e cartelle.
Sintassi generale:
find percorso opzioni
Qui il percorso è "$cartella", cioè la directory scelta dall’utente.
Opzioni usate:
-maxdepth 1: ferma la ricerca al primo livello;-type f: seleziona solo gli elementi di tipo file.Quindi il comando cerca tutti i file presenti direttamente dentro la cartella, senza entrare nelle sottocartelle.
|find ... | wc -l
La pipe passa l’output del comando di sinistra come input del comando di destra.
wc -l
wc significa word count, ma può contare varie cose.
Con l’opzione -l conta il numero di righe.
Poiché find stampa un file per riga, wc -l conta quanti file sono stati trovati.
num_dir=$(find "$cartella" -maxdepth 1 -type d | wc -l)
È quasi identico alla riga precedente, ma cambia una sola opzione:
-type d
Qui find cerca solo le directory.
Attenzione però: find include anche la cartella stessa.
Quindi se dentro Documenti ci sono 3 sottocartelle, il risultato sarà 4:
echo "Numero di file: $num_file"
echo "Numero di cartelle: $((num_dir - 1))"
La prima riga mostra semplicemente il numero di file.
La seconda usa un’espressione aritmetica Bash:
$((num_dir - 1))
Significa: calcola num_dir - 1.
Serve a togliere dal conteggio la cartella principale.
echo "File .txt presenti:"
for file in "$cartella"/*.txt
do
if [ -f "$file" ]; then
echo "$(basename "$file")"
fi
done
forfor file in "$cartella"/*.txt
Vuol dire: per ogni elemento che corrisponde al modello *.txt, esegui il blocco seguente.
*.txt è un pattern di shell:
* = qualsiasi sequenza di caratteri;.txt = finale del nome.
Quindi seleziona tutti i file che finiscono in .txt.
Esempi validi:
appunti.txtelenco.txtNon validi:
foto.jpgtesto.docdo ... doneDelimitano il corpo del ciclo.
-fif [ -f "$file" ]; then
-f verifica se il percorso è un file normale.
Questo controllo è utile perché, in certi casi, se non esistono file .txt, il pattern
può non comportarsi come ci si aspetta.
basenamebasename "$file"
Il comando basename estrae solo il nome finale del file, togliendo il percorso.
Esempio:
se file vale:
Documenti/prova.txt
allora:
basename "$file"
restituisce:
prova.txt
echo "$(basename "$file")"
echo "Report salvato in report.txt"
Stampa semplicemente un messaggio per informare l’utente che il file di report è stato creato.
{
echo "REPORT CARTELLA: $cartella"
echo "Numero di file: $num_file"
echo "Numero di sottocartelle: $((num_dir - 1))"
echo "File .txt presenti:"
for file in "$cartella"/*.txt
do
if [ -f "$file" ]; then
basename "$file"
fi
done
} > report.txt
{
comandi
}
Le parentesi graffe raggruppano più comandi in un unico blocco.
>} > report.txt
Il simbolo > redirige tutto l’output del blocco dentro un file.
Quindi invece di mostrare i risultati a schermo, li scrive in:
report.txt
Attenzione: > sovrascrive il file se esiste già.
Se volessi aggiungere in coda, useresti:
>>
Nel programma alcune righe usano echo per mostrare dati a video.
Nel blocco finale gli stessi dati vengono scritti su file grazie a >.
| Comando / elemento | Significato |
|---|---|
echo |
Stampa testo a video |
read |
Legge input da tastiera |
if [ condizione ] |
Esegue un blocco solo se la condizione è vera |
-d |
Vero se il percorso è una directory |
-f |
Vero se il percorso è un file |
! |
Nega la condizione |
exit 1 |
Termina lo script con errore |
find |
Cerca file e cartelle |
-maxdepth 1 |
Non scende oltre il primo livello |
-type f |
Solo file |
-type d |
Solo directory |
wc -l |
Conta il numero di righe |
basename |
Toglie il percorso e lascia solo il nome del file |
for |
Ripete un blocco per ogni elemento di una lista |
> |
Redirige l’output in un file, sovrascrivendolo |
In questo script il file report.txt viene creato nella cartella da cui si esegue lo script,
non necessariamente dentro la cartella analizzata.