View Full Version : Shell unix per ordinare file in cartelle
Buongiorno a tutti,
dovrei creare una shell unix che analizza il contenuto di
una cartella e ordina i vari file in sottocartelle.
Ad es nella cartella sono presenti i file a1.txt, a2.txt, b1.txt
il risultato sarebbe avere i file 'a' tutti dentro la sottocartella 'filea'
e i file 'b' tutti dentro la sottocartella 'fileb'.
E' possibile una cosa del genere, se si come?!?
Grazie
Cosa intendi per creare una shell unix?
Scrivere una shell da 0 che ti permetta di fare cio' che dici tu, o uno script per una shell
gia' esistente (es bash) ?
Cosa intendi per creare una shell unix?
Scrivere una shell da 0 che ti permetta di fare cio' che dici tu, o uno script per una shell
gia' esistente (es bash) ?
Ciao, scriverla da 0! :cry:
dawid999
27-10-2008, 16:59
Ciao, scriverla da 0! :cry:
script di shell ;)
script di shell ;)
Sfortunatamente le mie conoscenze di unix sono pochine...potresti spiegarmi cosa intendi?!?
Grazie
megamitch
27-10-2008, 17:57
Ciao,
quello che ti serve è uno "script" (o un programma se preferisci) che esegua le operazioni che ti servono.
La "shell" è l'ambiente dentro il quale il programma (o script) viene eseguito.
Ciao
M.
PS: per i puristi, non vogliatemene se ho usato un linguaggio "scorretto"... :)
script di shell ;)
Si credo anch'io :p
Ma magari parlava di un progetto universitario o chissa' cosa :)
Facci sapere se ti serve uno script.
ti posto una cosa che mi e' venuta di getto (non l'ho testato, quindi potrei aver fatto qualche cazzata, ma l'idea di base c'e')...
ma ovviamente ti consiglio di studiarti almeno un pelino di bash (almeno sapere cos'e' una shell e cosa uno script!)
#!/bin/bash
for file in $(ls *.txt)
do
directory=file$(echo $file | cut -c 1)
mkdir -p $(pwd)/$directory
mv $file $directory/
done
a dire la verita' adesso che ci ho pensato 10 secondi in piu' mi e' venuto in mente un metodo decisamente piu' veloce (se ci sono tanti file)...
ma adesso vado ad allenamento... magari posto piu' tardi!
ok avevo 5 minuti :D
#!/bin/bash
for letter in $(ls *.txt | cut -c 1 | uniq)
do
mkdir -p ./file$letter
mv $letter*.txt ./file$letter
done
Ciao,
quello che ti serve è uno "script" (o un programma se preferisci) che esegua le operazioni che ti servono.
La "shell" è l'ambiente dentro il quale il programma (o script) viene eseguito.
Ciao
M.
PS: per i puristi, non vogliatemene se ho usato un linguaggio "scorretto"... :)
Corretto...scusate la terminologia errata!
Ed è appunto un prgetto universitario!
Ci provo subito, grazie mille
Ps.: un ulteriore precisazione i nome dei file è a0001.txt .. a0011.txt e la cartella per uno sarà
cartella1 mentre per l'altro cartella11.
Corretto...scusate la terminologia errata!
Ed è appunto un prgetto universitario!
Ci provo subito, grazie mille
Ps.: un ulteriore precisazione i nome dei file è a0001.txt .. a0011.txt e la cartella per uno sarà
cartella1 mentre per l'altro cartella11.
beh le basi te le ho fatte vedere... adesso con una buona guida: http://tldp.org/LDP/abs/html/ e un po di buona volonta' vedrai che ce la fai a modificare lo script e a fare quello che ti serve...
ovviamente per suggerimenti e spiegazioni, ti do' una mano volentieri...
magari studia un attimo e poi posta il tuo script (con spiegazione di quello che vuoi fare quasi riga per riga) e noi ti diamo una mano a sistemare!
buon lavoro!
Corretto...scusate la terminologia errata!
Ed è appunto un prgetto universitario!
Ci provo subito, grazie mille
Ps.: un ulteriore precisazione i nome dei file è a0001.txt .. a0011.txt e la cartella per uno sarà
cartella1 mentre per l'altro cartella11.
Almeno ci hai provato a farlo?
per policy, questi post dovrebbero essere corredati dal codice che uno prova a scrivere.
Almeno ci hai provato a farlo?
per policy, questi post dovrebbero essere corredati dal codice che uno prova a scrivere.
Certo che ci ho provato...
Grazie HexDEF6 per il manuale!!
Ora ci picchio un pò la testa!
Graziiiiiiiieeeeee!
Ciao a tutti,
grazie ai vostri consigli e al manuale sono riuscito a fare tutto il progetto
e non solo la piccola parte di cui chiedevo!
Mi sono restati due dubbi:
1) substring: sui vari manuali ho trovato questo codice:
stringZ=abcABC123ABCabc
echo `expr match "$stringZ" 'abc[A−Z]*.2'`
echo `expr "$stringZ" : 'abc[A−Z]*.2'`
Provando ad eseguirlo l'output a video sono giustamente due 8...in quanto la stringa abc o ABC è ripetuta 4 volte.
Ma non ne esiste un substring che faccia una cosa del genedere:
stringZ=abcABC123ABCabc
echo substr($stringZ,6,3)
Il cui output a video sarà in questo caso 123.
2) raplace: in questo caso, sempre sui manuali, ho trovato che il
replace si può fare con le seguenti istruzioni:
stringZ=abcABC123ABCabc
echo ${stringZ/#abc/XYZ}
echo ${stringZ/%abc/XYZ}
In entrambi i casi il risultato è bad substitution.
Quindi come posso sostituire una parte di da una stringa, esempio:
stringZ=abcABC123ABCabc
echo replace($stringZ,abc,'')
Il cui output a video sarà in questo caso ABC123ABC.
Scusate le domande sicuramente banali ma è la prima volta che mi "scontro"
con questo modo di scrivere programmi.
Grazie mille
Ciao a tutti,
grazie ai vostri consigli e al manuale sono riuscito a fare tutto il progetto
e non solo la piccola parte di cui chiedevo!
Mi sono restati due dubbi:
1) substring: sui vari manuali ho trovato questo codice:
stringZ=abcABC123ABCabc
echo `expr match "$stringZ" 'abc[A−Z]*.2'`
echo `expr "$stringZ" : 'abc[A−Z]*.2'`
Provando ad eseguirlo l'output a video sono giustamente due 8...in quanto la stringa abc o ABC è ripetuta 4 volte.
Ma non ne esiste un substring che faccia una cosa del genedere:
stringZ=abcABC123ABCabc
echo substr($stringZ,6,3)
Il cui output a video sarà in questo caso 123.
se ho capito cosa ti serve, si fa cosi:
echo ${stringZ:6:3}
2) raplace: in questo caso, sempre sui manuali, ho trovato che il
replace si può fare con le seguenti istruzioni:
stringZ=abcABC123ABCabc
echo ${stringZ/#abc/XYZ}
echo ${stringZ/%abc/XYZ}
In entrambi i casi il risultato è bad substitution.
Quindi come posso sostituire una parte di da una stringa, esempio:
stringZ=abcABC123ABCabc
echo replace($stringZ,abc,'')
Il cui output a video sarà in questo caso ABC123ABC.
Scusate le domande sicuramente banali ma è la prima volta che mi "scontro"
con questo modo di scrivere programmi.
Grazie mille
stai usando una bash?
perche' le sostituzioni funzionano proprio cosi!
stringZ=abcABC123ABCabc
echo ${stringZ/#abc/XYZ}
il risultato sara' :
XYZABC123ABCabc
il # davanti indica che fara' la sostituzione solo se abc e' all'inizio della stringa
echo ${stringZ/%abc/XYZ}
il risultato sara':
abcABC123ABCXYZ
il % sta ad indicare che la sostituzione verra' fatta solo se la fine della stringa e' abc
se invece vuoi sostituire tutte le ricorrenze devi fare:
echo ${stringZ//abc/XYZ}
XYZABC123ABCXYZ
o se metti:
echo ${stringZ//abc/}
otterrai:
ABC123ABC
spero di aver chiarito!
Ok, tutto chiaro...solo che sia per
echo ${stringZ:6:3} che per
echo ${stringZ//abc/}
il risultato è
${stringZ:6:3}: bad substitution
${stringZ//abc/}: bad substitution
Grazie mille per la spiegazione
Ok, tutto chiaro...solo che sia per
echo ${stringZ:6:3} che per
echo ${stringZ//abc/}
il risultato è
${stringZ:6:3}: bad substitution
${stringZ//abc/}: bad substitution
Grazie mille per la spiegazione
ma che sistema operativo stai usando?
che shell?
perche' queste funzionano sicuramente sotto bash (le ho provate proprio adesso!)... ma magari sotto qualche altra shell no...
prima di lanciare uno di questi script lancia:
bash
e poi vai con lo script
SunOS 5.8
Neanche sotto bash funzionano:
bash-2.03$ prova.sh
file_0001.txt
file_0011.dat
file_0012.dat
/shell/prova.sh[34]: ${stringZ:6:3}: bad substitution
bash-2.03$
Grazie
SunOS 5.8
Neanche sotto bash funzionano:
bash-2.03$ prova.sh
file_0001.txt
file_0011.dat
file_0012.dat
/shell/prova.sh[34]: ${stringZ:6:3}: bad substitution
bash-2.03$
Grazie
azz, la guida credo si riferisca alla versione 3 di bash...
e infatti nel mio caso:
$ bash --version
GNU bash, version 3.2.39(1)-release (i486-pc-linux-gnu)
Copyright (C) 2007 Free Software Foundation, Inc.
Infatti noi abbaimo una misera version 2.03.0(1)-release...:muro:
Secondo te ci sono alternative?!?
Grazie
Infatti noi abbaimo una misera version 2.03.0(1)-release...:muro:
Secondo te ci sono alternative?!?
Grazie
beh, puoi usare sed e awk, ma per fare certe cose come modificare una stringa, mi sembrano un pelo esagerati...
vedo se magari trovo la versione dell'advanced bash scripting guide per la bash 2
dovresti trovarti la guida alla versione 2.8
dalla 3 in poi inizia a parlare anche di bash 3
Ok...visto che cmq andrei a lavorare sulla stessa stringa e solo in una particolare condizione provo anche sed e awk!
Grazie mille
Con sed e awk è un casino...per quella parte devo inventare altro...! :)
Mi ricollego a questo argomento:
sono cotretto ad untilizzare l'awk quindi:
for file in $(ls $Dir_Orig*.txt)
do
print $file
num = `awk '{substr($file,1,2)'}`
echo $num
if [ "$num" < "10" ]; then
echo minore di 10
Dir_dest = Dir_dest + $num
mv $file $Dir_dest
else
echo maggiore di 10
Dir_dest = Dir_dest + 1 + $num
mv $file $Dir_dest
fi
done
Il problema è che sembra restare il loop sull'awk...rimane fermo dopo il print del file e non si muove +...qualcuno sa dirmi il perchè?!? :p
Mi ricollego a questo argomento:
sono cotretto ad untilizzare l'awk quindi:
for file in $(ls $Dir_Orig*.txt)
do
print $file
num = `awk '{substr($file,1,2)'}`
echo $num
if [ "$num" < "10" ]; then
echo minore di 10
Dir_dest = Dir_dest + $num
mv $file $Dir_dest
else
echo maggiore di 10
Dir_dest = Dir_dest + 1 + $num
mv $file $Dir_dest
fi
done
Il problema è che sembra restare il loop sull'awk...rimane fermo dopo il print del file e non si muove +...qualcuno sa dirmi il perchè?!? :p
cosi a occhio (pensando che hai una bash 2 sotto sunos)... potrebbe essere che awk non sa cosa sia $file...
prova cosi (al posto di: num = `awk '{substr($file,1,2)'}`)
num = `awk -v file=$file '{substr(file,1,2)'}`
e dimmi se funziona o magari cosi:
num=$(awk -v file=$file '{substr(file,1,2)'})
nulla...sempre
awk: syntax error near line 1
awk: bailing out near line 1
:mc:
nulla...sempre
awk: syntax error near line 1
awk: bailing out near line 1
:mc:
avrai anche una versione di awk del 1902 :D
cazzarola ma perche' un sunos di 10 ani fa?????????
vai di man awk e vedi come passargli variabili
o magari nel tuo scipt metti un print $file (dentro l'awk prima di tutto il resto) in modo da vedere se la variabile viene passata...
Ehehe...sfortunatamente non dipende da me...:cry: mi devo prendere macchina fatta e finita...senza possibilità di modificare nulla! :cry:
#!/bin/bash
Dir_Orig="./"
echo $Dir_Orig
for file in $(ls $Dir_Orig*.txt)
do
echo "il nome del file: " $(basename $file)
num=$(echo $(basename $file) | awk '{ print substr($0,2,2) }')
echo $num
if [ "$num" -lt "10" ]; then
echo minore di 10
Dir_dest=$num
mkdir -p $Dir_dest
mv $file $Dir_dest
else
echo maggiore di 10
Dir_dest=$num
mkdir -p $Dir_dest
mv $file $Dir_dest
fi
done
questo dovrebbe funzionare per file fatti cosi:
a01.txt ==> nella dir 01
a02.txt ==> nella dir 02
a03.txt ==> nella dir 03
b01.txt ==> nella dir 01
c01.txt ==> nella dir 01
c02.txt ==> nella dir 02
l'if non serve ad un tubo (a parte stampare se il numero e' maggiore o minore di 10)
#!/bin/bash
Dir_Orig="./"
echo $Dir_Orig
for file in $(ls $Dir_Orig*.txt)
do
echo "il nome del file: " $(basename $file)
num=$(echo $(basename $file) | awk '{ print substr($0,2,2) }')
echo $num
if [ "$num" -lt "10" ]; then
echo minore di 10
Dir_dest=$num
mkdir -p $Dir_dest
mv $file $Dir_dest
else
echo maggiore di 10
Dir_dest=$num
mkdir -p $Dir_dest
mv $file $Dir_dest
fi
done
questo dovrebbe funzionare per file fatti cosi:
a01.txt ==> nella dir 01
a02.txt ==> nella dir 02
a03.txt ==> nella dir 03
b01.txt ==> nella dir 01
c01.txt ==> nella dir 01
c02.txt ==> nella dir 02
l'if non serve ad un tubo (a parte stampare se il numero e' maggiore o minore di 10)
Provo a fare alre prove...!
secondo me al posto del awk sarebbe meglio usare il cut -c
ho fatto così e sembra funzionare correttamente...
for num in `ls $Dir_Orig*.dat | awk '{ print substr($0, 6,3) }'`
provo con qualche caso particolare!
Grazie mille a tuttiiiiiiiiii! :)
vBulletin® v3.6.4, Copyright ©2000-2026, Jelsoft Enterprises Ltd.