PDA

Visualizza la versione completa : [BASH]: Conteggio file e directory


valer_85
24-05-2006, 16:08
ecco un altro problema...
devo passare allo script una directory e di questa directory devo contare il numero dei file e dei link e delle sottocartelle...nel caso di una sottodirectory devo entrare dentro di essa ricorsivamente... ecco la mia idea, xò non funziona xkè ogni volta ke ricomincia la ricorsione le variabili si riazzerano...
come posso fare? grazie


#!/bin/sh
ndir=0;
nfile=0;
nlink=0;
PATH=$PATH:/home/valekate/Desktop
cd $1
for i in *; do
if [ -d $i ]; then
let "ndir+=1"
cont.sh $1/$i
elif [ -f $i ]; then
let "nfile+=1"
elif [ -h $i ]; then
let "nlink+=1"
fi
done

echo il numero di direc è $ndir
echo il numero di files è $nfile
echo il numero di link è $nlink

andbin
24-05-2006, 17:23
Originariamente inviato da valer_85
ecco un altro problema...
devo passare allo script una directory e di questa directory devo contare il numero dei file e dei link e delle sottocartelle...nel caso di una sottodirectory devo entrare dentro di essa ricorsivamente... ecco la mia idea, xò non funziona xkè ogni volta ke ricomincia la ricorsione le variabili si riazzerano...Uhm ... non è banale!
In questo caso, lo script eseguito in maniera ricorsiva dovrebbe poter restituire dei dati al padre in modo da effettuare una sommatoria ma ... uno script "figlio" non può modificare le variabili del padre e neanche (in modo semplice) restituire dei dati.

Io lo farei così (sempre usando la ricorsione, ma tramite una funzione):

#!/bin/bash

function count_dir_informations ()
{
local DIR="$1"
cd "$DIR"

for F in *; do
if [ "$F" != "." -a "$F" != ".." ]; then
if [ -d "$F" ]; then
COUNT_D=$[COUNT_D+1]

if [ -x "$F" ]; then
count_dir_informations "$DIR/$F"
cd $DIR
else
echo "Impossibile entrare in $DIR/$F"
fi
elif [ -f "$F" ]; then
COUNT_F=$[COUNT_F+1]
elif [ -L "$F" ]; then
COUNT_L=$[COUNT_L+1]
fi
fi
done
}

COUNT_F=0
COUNT_D=0
COUNT_L=0

glob_dot_filenames=1

count_dir_informations $1

echo "Numero di file: $COUNT_F"
echo "Numero di directory: $COUNT_D"
echo "Numero di link: $COUNT_L"
Se però ci sono dei link "circolari" o dei link che puntano a directory più sopra (nell'albero delle directory) .... credo che lo script sia fottuto. :fagiano:

valer_85
24-05-2006, 18:15
uhm... troppo complesso, mi dispiace... il prof capirebbe ke nn è farina del mio sacco :)
ankio avevo pensato alla soluzione del padre-figlio xò poi era venuto a galla quel problema...
e questa soluzione? : faccio 1 script principale ke ne gestisce 3: 1 per il conteggio dei file, 1 1 per le dir, e uno x i link, e ognuno ritorna il valore facendo exit(valore)...
può funzionare?o ho scritto delle assurdità ?( molto probabile :D )

andbin
24-05-2006, 20:42
Originariamente inviato da valer_85
uhm... troppo complesso, mi dispiace... il prof capirebbe ke nn è farina del mio sacco :)Beh, certo ... io volevo solo mostrare la "mia" personale soluzione. :)

Tra l'altro ho usato delle cose "particolari". Per esempio quando fai for F in * in realtà non riusciresti a prendere tutti i file possibili. Come sai su Linux ci sono molti file (specialmente nelle home directory degli utenti) che iniziano con il punto '.'. Per prendere anche questi file usando il *, si può impostare una variabile "speciale" della bash che è appunto glob_dot_filenames (poi però tira fuori anche il . e .., quindi sono da filtrare, ecc...).


Originariamente inviato da valer_85
faccio 1 script principale ke ne gestisce 3: 1 per il conteggio dei file, 1 1 per le dir, e uno x i link, e ognuno ritorna il valore facendo exit(valore)...Ehm ... no. Idea pessima quella di far restituire un valore. Normalmente si restituisce un codice di stato: 0 successo, 1 errore, ecc...
Tra l'altro, se non mi sbaglio, il massimo valore che uno script può restituire è 255 (in pratica usa 1 byte per il valore di ritorno).

valer_85
24-05-2006, 22:52
capisco...e 1 soluzione 1 pò + semplice della tua?
cmq a guardarci bene nn sembra poi così complessa da spiegare... certo se avessi dovuta farla io nn c sarei mai riuscito :D
se nn esistono soluzioni + semplici xò mi adatto :fighet:
grazie cmq dell'aiuto ke mi stai dando, FONDAMENTALE direi! :zizi:

andbin
25-05-2006, 10:58
Originariamente inviato da valer_85
capisco...e 1 soluzione 1 pò + semplice della tua?Sì, è possibile. Il tuo script iniziale non è proprio sbagliato. Salvo il fatto, ad esempio, che hai usato un test con -h che sinceramente non so cos'è. :confused:

La soluzione tramite ricorsione va bene. Nel tuo caso useresti la ricorsione dello script intero. Il problema, come abbiamo già evidenziato, è dove tenere le informazioni sui conteggi!
Una soluzione ci sarebbe: tenere le informazioni su un file temporaneo. Dal momento che c'è solamente 1 script in esecuzione per volta (anche con la ricorsione), puoi tenere i dati su 1 riga di un file temporaneo (messo sotto /tmp o dove vuoi).

In pratica nello script tieni delle variabili che contengono dei conteggi parziali. Alla fine dello script, leggi il file temporaneo, prendi i singoli valori, ci aggiungi i valori parziali e riscrivi il file.
È una possibilità, puoi provare così. :)

valer_85
25-05-2006, 11:44
eccellente idea :D grazie mille! nei prossimi giorni provo poi t faccio sapere, ora mi devo dedicare allo studio di un'altra materia ke giovedì c'è l'esame...

ah, il -h da quel ke ho letto in 1 manuale serve x vedere se è un link... sia -h che -L ... poi nn so se è giusto.
grazie ancora, alla prossima.
ciao e buon weekend :ciauz:

andbin
25-05-2006, 12:23
Originariamente inviato da valer_85
ah, il -h da quel ke ho letto in 1 manuale serve x vedere se è un link... sia -h che -LSì, è vero. Le versioni più recenti della bash (ho visto adesso su una bash 2.0) hanno anche il -h mentre le versioni più vecchie (ho visto sulla 1.14) hanno solamente il -L. :)

ibykos
26-05-2006, 10:59
Scusami ma non ho il man a portata di mano.
Potresti provare a combinare wc ed ls

ls $DIR | wc

non mi ricordo le opzioni da passare ad ls e wc per ottenere:

da ls tutti i files, dirs e links contenuti
da wc solo il numero di parole trovate

poi, ricorsivamente, per ogni directory, richiami lo script, che restituisce il numero di parole contate

in pseudo codice risulterebbe




for $parola in ls $DIR
do
if test ... è una directory
$nfiles += richiama ricorsivamente lo script
elif
done

$numero di file = ls $DIR | wc

echo $numero di file o return $numero (quel che è)

valer_85
05-06-2006, 17:01
grazie ibycos, ma x ora uso l'altra soluzione... o almeno provo...
ecco un altro quesito, come creo un file di testo? ho trovato il comando vi, ma nn mi sembra facile da gestire...

Loading