[Script] spostare file
1 #! /bin/sh 2 if (test $# -ne 2) then 3 echo "Uso: $0 estensione direttorio" 4 exit -1 5 fi 6 if (test ! -d $2) then 7 echo "Il direttorio $2 non esiste, adesso lo creo" 8 mkdir $2 9 fi 10 echo "Dimmi la parola che devo cercare: " 11 read parola 12 for i in *.$1 13 do 14 echo "Esamino il file $i" 15 if (grep $parola $i) then 16 echo "Sposto $i in $2" 17 mv $i $2 18 fi 19 done
Premesso che sono alle primissime armi,ho capito che lo script serve a spostare in un direttorio specificato dall’utente tutti i file con una certa estensione (anch’essa specificata dall’utente) e che contengono una certa parola (che lo script chiede all’utente),e se il direttorio specificato dall’utente non esiste, viene creato dallo script.
Le cose che non mi sono chiare sono :
riga 2 :
if (test $# -ne 2), che significa -ne? Cosa indica il 2?
riga 6 :
if (test ! -d $2)...tutta

Inoltre ora mi si richiede di aggiungere allo script la possibilità di invocarlo con due eventuali opzioni -s e -n (ad es. mioscript [-s] [-n]
ovviamente non so da dove partire...

Risposte
"Mifert4":
Le cose che non mi sono chiare sono :
riga 2 :if (test $# -ne 2), che significa -ne? Cosa indica il 2?
$#è una variabile che contiene il numero degli argomenti passati allo script.
-neè un operatore del comando
test(1)e signfica "non uguale a". Quindi la condizione dell'if è verificata se il numero degli argomenti sulla riga di comando non è uguale a 2.
riga 6 :if (test ! -d $2)
se il parametro (della riga di comando)
$2non (operatore
!) è una directory (
-d) allora...
Inoltre ora mi si richiede di aggiungere allo script la possibilità di invocarlo con due eventuali opzioni -s e -n [...]
ovviamente non so da dove partire...
Ci sono vari modi, prova a guardare il comando
getoptsdella shell. Comunque, visto che usi Linux, trovi maggiori informazioni nella manpage della shell (comando man sh, anche se penso che tu lo sappia questo).

#! /bin/sh if (test ! -d $2) then echo "Il direttorio $2 non esiste, adesso lo creo" mkdir $2 fi getopts first getopts second if (test $first = "-s" -o $second = "-s") cp -r $i $2 rm -rf $i $2 fi if(test first ! "-n" | second ! "-n") echo "Sono da spostare i file che contengono la parola...: " read parola for i in *.$1 do echo "Esamino il file $i" if (grep $parola $i) then echo "Sposto $i in $2" else echo "Sono da spostare i file che contengono la parola...: " read parola for i in *.$1 do echo "Esamino il file $i" if (grep ! $parola $i) then echo "Sposto $i in $2" fi done
Ho tentato di fare qualcosa,ma ovviamente sono troppe le cose che non so.Ad esempio l'operazione di sovrascrittura credo proprio che sia grossolana se non completamente sbagliata...
Ciao, ti do qualche suggerimento.
[list=1]
[*:3bkfj04x]getopts
ti conviene usare un ciclo while per scandire gli argomenti con questa struttura
[/*:m:3bkfj04x]
[*:3bkfj04x] opzione -s (sovrascrittura)
Puoi ad esempio impostare a "" (stringa vuota) una variabile di nome sovrascrivi, che imposterai/cambierai a "-f" nel
In questo modo, quando poi andrai a a copiare i file, passerai questa variabile sovrascrivi al comando cp.
[/*:m:3bkfj04x]
[*:3bkfj04x] opzione -n (non presente)
Stesso discorso di prima. Definisci all'inizio del file una variabile di nome presente ad esempio con un certo valore, che modificherai poi nel
Quale valore assegnare di default a questa variabile? Be', puoi sfruttare le opzioni di grep, in modo da fargli selezionare a lui quali file contengono e quali non contengono la parola da cercare. Precisamente
magari aggiungendo un preventivo controllo sull'esistenza di un analogo file nella directory di destinazione nel caso l'opzione sovrascrivi sia assente, in modo da saltarlo o segnalare la cosa tramite un messaggio.[/*:m:3bkfj04x][/list:o:3bkfj04x]
HTH
P.S. Ricordati inoltre di controllare che siano stati passati il nome della directory di destinazione e l'estensione.
[list=1]
[*:3bkfj04x]getopts
ti conviene usare un ciclo while per scandire gli argomenti con questa struttura
while getopts "ns" opzione do case "${opzione}" in s) # opzione -s, fai qualcosa n) # opzione -n, fai qualcosa ?) # opzione sconosciuta done
[/*:m:3bkfj04x]
[*:3bkfj04x] opzione -s (sovrascrittura)
Puoi ad esempio impostare a "" (stringa vuota) una variabile di nome sovrascrivi, che imposterai/cambierai a "-f" nel
caseprecedente quando ${opzione} è uguale a
s, cioè l'utente ha richiesto la sovrascrittura dei file.
In questo modo, quando poi andrai a a copiare i file, passerai questa variabile sovrascrivi al comando cp.
[/*:m:3bkfj04x]
[*:3bkfj04x] opzione -n (non presente)
Stesso discorso di prima. Definisci all'inizio del file una variabile di nome presente ad esempio con un certo valore, che modificherai poi nel
casese viene incontrata l'opzione -n
Quale valore assegnare di default a questa variabile? Be', puoi sfruttare le opzioni di grep, in modo da fargli selezionare a lui quali file contengono e quali non contengono la parola da cercare. Precisamente
[*:3bkfj04x]-l (elle) fa in modo che grep dia in output i nomi dei file che contengono la parola[/*:m:3bkfj04x]
[*:3bkfj04x]-L fa invece in modo che grep dia in output i nomi dei file che NON contengono la parola.[/*:m:3bkfj04x][/list:u:3bkfj04x]
Quindi all'inizio puoi assegnare alla variabile presente il valore -l, per poi eventualmente cambiarlo in -L se è presente l'opzione -n.[/*:m:3bkfj04x]
[*:3bkfj04x] copia/sovrascrittura dei file
Lo puoi fare ad esempio con un ciclo for sui file forniti da egrep, in questo modo
for f in $(grep ${presente} *.$1) do cp ${sovrascrivi} ${f} $2 done
magari aggiungendo un preventivo controllo sull'esistenza di un analogo file nella directory di destinazione nel caso l'opzione sovrascrivi sia assente, in modo da saltarlo o segnalare la cosa tramite un messaggio.[/*:m:3bkfj04x][/list:o:3bkfj04x]
HTH
P.S. Ricordati inoltre di controllare che siano stati passati il nome della directory di destinazione e l'estensione.
Nuovo tentativo,ma non fa ancora quello che dovrebbe
Al di la del fatto che l'operazione di spostamento non tiene ancora conto del numero di argomenti,perchè non mi sembrava "normale" fare ogni volta il controllo che ho fatto qui

#! /bin/sh if (test $# -lt 2) then echo "Uso: $0 estensione direttorio" exit -1 fi if (test $# -eq 4) then if (test ! -d $4) then echo "Il direttorio $4 non esiste, lo creo" mkdir $4 fi fi if (test $# -eq 3) then if (test ! -d $3) then echo "Il direttorio $3 non esiste, lo creo" mkdir $3 fi fi if (test $# -eq 2) then if (test ! -d $2) then echo "Il direttorio $2 non esiste, lo creo" mkdir $2 fi fi sovrascrivi="" presente="-l" while getopts "ns" opzione do case "${opzione}" in s) $sovrascrivi= "-f";; n) $presente= "-L";; ?) echo "Opzione sconosciuta" exit -1 esac done echo "Parola che devo cercare...? " read parola for i in *.$1 do echo "Esamino il file $i" for i in $(grep ${presente} $parola *.$1) do cp ${sovrascrivi} ${f} $2 done done
Al di la del fatto che l'operazione di spostamento non tiene ancora conto del numero di argomenti,perchè non mi sembrava "normale" fare ogni volta il controllo che ho fatto qui
if (test $# -eq 4) then... if (test $# -eq 3) then... if (test $# -eq 2) then...
"Mifert4":
Nuovo tentativo,ma non fa ancora quello che dovrebbe
Invece io direi che ci sei quasi. Devi solo rivedere l'ordine in cui esegui le varie istruzioni, aggiungere una parte che controlli quante opzioni sono stati richieste e migliorare l'ultimo blocco, quello che esegue la selezione dei file da copiare e poi li copia.
I suggerimenti in spoiler:
inoltre se ad esempio invoco lo script con l'opzione -h (una a caso) invece di scrivermi il messaggio di errore e invocare exit mi appare il messaggio di errore della shell
Sì, in questo caso per evitarne la stampa basta che fai precedere l'elenco delle tue opzioni da un due punti, quindi l'istruzione sarà
while getopts ":ns" opzione
#! /bin/sh if (test $# -lt 2) then echo "Uso: $0 estensione direttorio" exit -1 fi sovrascrivi="" presente="-n" while getopts ":ns" opzione do case "${opzione}" in s) $sovrascrivi= "-f";; n) $presente= "-L";; /?) echo "Opzione sconosciuta" exit -1;; esac done shift $OPTIND if (test ! -d $2) then echo "Il direttorio $2 non esiste, lo creo" mkdir $2 fi echo "Parola che devo cercare...? " read parola for i in $(grep ${presente} $parola *.$1) do cp ${sovrascrivi} ${i} $2 done
Non mi è chiaro l'uso di OPTIND, ma a giudicare dal messaggio di errore("grep: *.file: File o directory non esistente
") lo shift non fa effetto...
All'interno di questo ciclo for sarà utile ignorare la copia del file quando l'utente non ha richiesto la sovrascrittura e il file di destinazione esiste già
Non è quello che già succede usando cp in quel modo?
Ho aggiunto qualche commento (senza correggerlo) al tuo codice
Certamente, però come detto sarebbe utile (non obbligatorio) in modo da evitare di eseguire inutilmente il programma copy, ma anche senza tale controllo il programma funziona... o almeno si spera.
#! /bin/sh # questo blocco va spostato più avanti (vedi oltre) if (test $# -lt 2) then echo "Uso: $0 estensione direttorio" exit -1 fi # "sovrascrivi" è meglio inizializzarla a -n sovrascrivi="" # "presente" invece a -l (com'era prima) presente="-n" while getopts ":ns" opzione do case "${opzione}" in s) $sovrascrivi= "-f";; n) $presente= "-L";; # va usato uno slash \ non un backslash / /?) echo "Opzione sconosciuta" exit -1;; esac done # OPTIND è una variabile (il cui valore iniziale è 1) # incrementata da getopts ogni qual volta trova un'opzione # tra quelle definite (-n e -s). # Quindi... # # Inoltre devi aggiungere un controllo sul risultato del # calcolo precedente, di modo che venga eseguito lo shift # soltanto se tale risultato > 0 shift $OPTIND # il blocco iniziale va spostato qui # if (test ! -d $2) then echo "Il direttorio $2 non esiste, lo creo" mkdir $2 fi echo "Parola che devo cercare...? " read parola for i in $(grep ${presente} $parola *.$1) do # come detto potresti aggiungere un controllo (if) # per ignorare i file che esistono già nella # directory di destinazione, nel caso l'utente # non abbia specificato l'opzione -n, in questo # modo eviti di eseguire inutilmente il programma cp cp ${sovrascrivi} ${i} $2 done
"anonymous_be1147":
All'interno di questo ciclo for sarà utile ignorare la copia del file quando l'utente non ha richiesto la sovrascrittura e il file di destinazione esiste già
Non è quello che già succede usando cp in quel modo?
Certamente, però come detto sarebbe utile (non obbligatorio) in modo da evitare di eseguire inutilmente il programma copy, ma anche senza tale controllo il programma funziona... o almeno si spera.

Domanda/curiosità... come mai usi
P.S: direttorio non si può proprio sentire
teste non le
[]per le verifiche?
P.S: direttorio non si può proprio sentire

@anonymous_be1147 Ora ci provo...ce la posso fare
Era già impostato così...
hai ragione...ma è l'influenza del professore...

"Luc@s":
Domanda/curiosità... come mai usiteste non le[]per le verifiche?
Era già impostato così...

"Luc@s":
P.S: direttorio non si può proprio sentire

Non ce la posso fare.
Mi è venuto in mente questo,ma non so se sbaglio la sintassi o altro...
Mi è venuto in mente questo,ma non so se sbaglio la sintassi o altro...
n=$OPTIND-1 if (test n -gt 0) shift $n fi
"Mifert4":
Non ce la posso fare.
Mi dispiace contraddirti, ma l'hai praticamente finito.

Mi è venuto in mente questo,ma non so se sbaglio la sintassi o altro...
n=$OPTIND-1 if (test n -gt 0) shift $n fi
Esattamente è un problema di sintassi. Se scrivi
n=$OPTIND-1, alla variabile n viene assegnato il valore di OPTIND, seguito da un segno meno e poi da un 1, cioè una stringa di caratteri. Invece per eseguire dei calcoli aritmetici devi usare o il comando expr(1) oppure la cosiddetta espansione aritmetica
$(( )), cioè scrivere
n=$((${OPTIND}-1)).
Ora non ti resta che preparare dei test per controllare a fondo lo script.

C'erano altri errori: nell'if in questione dopo la parentesi non ci ho messo il then...e nel case: nelle lettere in parentesi (n ed s) ci andava il ' - ' d'avanti.
Ora comunque funziona...GRAZIE MILLE
Ora comunque funziona...GRAZIE MILLE
