[Risolto] Script per spostare dei file

Salve a tutti, avrei bisogno di un aiuto e ringrazio anticipatamente. Dovrei spostare file secondo la data di modifica.
Esempio: spostare tutti i file con la data di modifica 2008.

Grazie
Cordiali saluti

Ad occhio ti serve qualcosa di questo tipo:

$ find /directory_principale -newermt "1 Jan 2008" ! -newermt "1 Jan 2009" -exec mv {} directory_destinazione \;

ma prima di eseguirlo con “mv”, che li sposterebbe, fai qualche prova con “ls -al”:

$ find /directory_principale -newermt "1 Jan 2008" ! -newermt "1 Jan 2009" -exec ls -al  {} \;

per verificare che i files trovati siano effettivamente quelli corretti

In ogni caso:

$ man find

edit: entrambi i comandi terminano con “backslash punto_e_virgola” e non con il solo “punto_e_virgola”. E’ colpa del tag code del forum che per ragioni di sicurezza non visualizza correttamente l’output

grazioso script.

[quote=virus]
grazioso script.[/quote]

…se funziona! :slight_smile: Non l’ho provato!

non funziona. ma è grazioso lo stesso.

ahahahahha!
dici davvero?
in teoria sembrava giusto (files con data modifica >= 1/1/2008 e NON >=1/1/2009)

Dove ho cannato?

sul secondo find dice che che -exec non ha argomenti.
funziona sicuramente così:

$ find /directory_principale -newermt "1 Jan 2008" ! -newermt "1 Jan 2009" | xargs -i ls {}

pensa con xargs!

Aspetta… questo perché manca il backslash che il tag code non mi visualizza… O sbaglio?

edit: comunque meglio “ls -lc” per visualizzare la data/ora di modifica

vuole la backslash, ma tu lo sai preferisco xargs, e per giunta deprecato… è più potente.
:slight_smile:

Mi sembra funzionare:

$ find . -newermt '17 March 2009' \! -newermt '18 March 2009' -exec ls -lc  {} BACKSLASH;

-rw-rw---- 1 zod zod 583680 17 mar 23:40 ./zod.tar.gz

ma ho scoperto che si incasina se gli metto una data futura a quella odierna (tipo domani) nella “and”:

$ find . -newermt '17 March 2009' \! -newermt '19 March 2009' -exec ls -lc  {} BACKSLASH;

-rwxrwxr---1 root    zod       1928 18 mar 19:25 duplicates.sh
-rw-rw---- 1 zod     zod     583680 17 mar 23:40 ./zod.tar.gz
-rw-rw---- 1 zod     zod      14481 18 mar 15:37 processi.1

@andreadb facci sapere va bene!

ovviamente dove ho scritto BACKSLASH ci va un “”

[ot]
Per far comparire backslash, a volte lo digito doppio e ne compare 1
[/ot]

"\\" \\\\\

solo una precisazione:
l’opzione “-newermt” usata nello script, è utilizzabile solo in findutils > 4.3.3

per chi avesse una versione precedente, la ricerca di un file “più nuovo di”, si può fare in altri modi, ad esempio forzando il timestamp di un file farlocco e cercare tutti quelli più nuovi di questo

touch -t 200802010000 dePrezzo
find /home/alberto -newer dePrezzo -exec ls -ltc  {} *backslash*; > reminder

Premessa:
scritta in pochi minuti, quindi provatela un po’, PRIMA.
C’e’ un bieco trucco (trovatelo) perche’ non avevo voglia
di scrivere man date :stuck_out_tongue: per verificare.

Divertitevi a migliorarla,
margini ce ne sono a “palate”,
oltretutto - si tratta piu’ di semplice aritmetica che altro.
Ad esempio, la prima cosa da fare sarebbe quella di controllare e proteggere gli argomenti.

Per i motivi appena esposti…
cosi’ come e’ fornisce solo la lista dei files,
quindi potrete usarla in pipe con il comando desiderato
oppure modificare direttamente la penultima riga.

Spero non si verifichino problemi di visualizzazione
(ok,ok un giorno studiero’ come usare i tag,
pigro sugno)

Uso:

Immaginiamo di chiamarla trovarange.sh:

$ trovarange.sh ./miacartella 20090310 20090318

–CUT------------------------------------
#!/bin/bash

- Lista i files modificati entro un intervallo di giorni

$1 Albero (cartella) in cui cercare

$2 Inizio data

$3 Fine data

Conversione data

Data2stamp ()
{ date --utc --date “$1” +%s
}

Differenza giorni tra le date

DiffGiorni ()
{ Secondi=$((($1)-($2)))
if ((Secondi < 0)); then
echo $((Secondi/-86400))
else
echo $((Secondi/86400));
fi
}

Test argomenti script

if ! “$1” ] || ! $2 ] || ! $3 ]; then
echo “”
echo " Script che usa “find” per cercare files in un intervallo di date"
echo “”
echo " Uso:"
echo " $ ./$0 /Cartella_di_ricerca aaaammgg aaaammgg"
echo “”
exit
fi

dir_ricerca="$1"
oggi=$(date +%s)
var2=$(Data2stamp $2)
var3=$(Data2stamp $3)

Termina se la data e’ errata

if (($var2 > $oggi)) || (($var3 > $oggi)); then
echo “$0 Errore: Impossibile cercare files con la data nel futuro! :)”
exit 255
fi

Ordina inizio e fine data

if (($var2 > $var3)); then
end=$var2
start=$var3
else
start=$var2
end=$var3
fi

Calcola differenza da oggi

inizio=$(($(DiffGiorni $oggi $start) +1))
fine=$(($(DiffGiorni $oggi $end) -1))

costruisce l’argomento per find

if (( $inizio > 0 )) && (( $fine >= 0 )); then
intervallo="-mtime -$inizio -mtime +$fine"
else
intervallo="-mtime -$inizio"
fi

Cerca i files (era ora)

verifica effettuando la lista dei files e relativa data

#find -L “$dir_ricerca” -type f -daystart $intervallo -printf “%h/%f\t%Ty%Tm%Td\n”
find -L “$dir_ricerca” -type f -daystart $intervallo -print
exit $?
–CUT------------------------------------

mmh la tabulazione e’ persa, ma la sostanza sembrerebbe a posto.

Fatemi sapere, se vi va :slight_smile:

molto graziosissimo.

L’ho realizzato abbastanza velocemente e dalle verifiche mi sembra tutto in ordine.
Sto solo avendo molta difficoltà a formattarlo con gli editor messi a disposizione nel forum.
Mi auguro non sia “saltata” un po’ di roba.
In sintesi lo script vi fa scegliere la directory da sfogliare, ed in essa vi fa cercare i file compresi in un intervallo di tempo.
Alla fine scrive tutto su di un log, e se volete, archivia quanto trovato.
Dalle prove fatte mi funziona praticamente tutto, spero solo che, ripeto, non ci siano stati aggrovigliamenti di codice dati dalla difficoltà di formattare il tutto in maniera adeguata.

edit: ho visto che è saltata un po’ di roba, come le parentesi quadre nei test … non so che fare,non posso allegare l’originale.
Se ritenete … potete piallare

#!/bin/bash
bg=’\E[37;44m’
b_bold="\033[1m"
e_bold="\033[0m"
today=$(date +%s)
b_red="\033[1;31m"
e_red="\033[0m"
todayName=$(date | cut -d" " -f2,3,6 | sed 's/ //g’)
archName="$todayName".tar
logName="$todayName".log
function chkSpaces()
{
for i in *; do
echo “$i” | grep -q " "
if [[ $? -eq 0 ]]; then
newName=$(echo $i | sed -e "s/ /
/g")
mv “$i” “$newName”
fi done
}
function selectDir()
{
echo
echo -e $bg$b_bold"Insert the dir in which you want to search …"$e_bold

select myDir in $(ls -d */) ; do

echo $myDir

dir_find=$myDir

break

done

}

function getDate()
{

cd $dir_find
chkSpaces

for i in *; do
date=$(ls -ld --time-style=+%Y%m%d $i | cut -d" " -f6)
if $((10#$date)) -le $((10#$endDate)) ]];

then

if $((10#$date)) -ge $((10#$beginDate)) ]];

then

echo $i >> $logName

fi
fi
done
}
function chkZero()
{
format=$(echo $1 | grep -e ‘^0[1-9]’)

if $format ]]; then

rightFormat=$1
else
rightFormat=0$1
fi
}

function chkDate()
{
echo

echo -e $bg$b_bold"Please insert the year … (YYYY)"$e_bold

read year

if $year -gt 2009 || $year -lt 1970 ]] ; then

echo "error: year must be between 1970 and 2009. "

exit
fi
echo -e $bg$b_bold"Insert month …(MM) "$e_bold

read month
if $month -lt 1 || $month -gt 12 ]]; then
echo “error: month must be a number between 1 and 12”
exit
fi
if $month -lt 10 ]]; then
chkZero $month
month=$rightFormat
fi
echo -e $bg$b_bold"Insert the day …(dd)"$e_bold
read day
if $day -lt 1 ]]; then
wrongDay
exit
fi
case $month in
[11,4,6,9])
if $day -gt 30 ]]; then
wrongDay
fi
;;
2)
if $day -gt 28 ]];then
wrongDay
fi
;;
*)
if $day -gt 31 ]];then
wrongDay
fi
;;
esac
if $day -lt 10 ]]; then
chkZero $day
day=$rightFormat
fi
}
function wrongDay()
{
echo "wrong day inserted … " exit
}

function createTar()
{
for i in cat $todayName.log;
do
if -f $i ] ; then
tar --append --file=$archName $i
fi
done;
}

clear
selectDir
clear
echo
echo
Now you have to give me two dates, a ‘FROM’ date and a
‘TO’ date. echo Give me them in 3 steps, in the format
YYYY, next MM, and finally dd.

echo I will find every file created in this interval.
echo
The directory is $dir_find
echo
echo -e $b_red"Now insert the ‘FROM’ date"$e_red
chkDate
beginDate=$year$month$day
echo
echo -e $b_red"Now insert the ‘TO’ date"$e_red
chkDate
endDate=$year$month$day
getDate
cat $todayName.log | more
echo echo echo “Do you want to create an archive of them? …[y/N]”

echo “(or press a key to quit)”
read create
if $create != “y” ]]; then
echo “… bye!”
else
createTar
fi
exit

posta di nuovo il listato corretto.
successivamente ripulirò la discussione.

ecco il listato
ne ho approfittato per fare una modifica al codice per permettere più operazioni di backup al giorno.
Sperèm sia tutto a posto (parentesi quadre a parte)

p.s.: il problema credo sia legato ad aver switchato tra gli editor (FCK,Tiny,…), non “reincollando” il codice nella textarea. Chiedo venia, non conosco XOOPS e non mi era mai successo un problema simile.

#!/bin/bash

bg=’\E[37;44m’
b_bold="\033[1m"
e_bold="\033[0m"
today=$(date +%s)
b_red="\033[1;31m"
e_red="\033[0m"
todayName=$(date | cut -d" " -f2,3,6 | sed ‘s/ /_/g’)
num=$RANDOM
archName="$num$todayName.tar"
logName="$num$todayName.log"

function chkSpaces()
{
for i in *; do
echo “$i” | grep -q " "
if [[ $? -eq 0 ]]; then
newName=$(echo $i | sed -e “s/ /_/g”)
mv “$i” “$newName”
fi
done
}

function selectDir()
{
echo
echo -e $bg$b_bold"Insert the dir in which you want to search …"$e_bold

select myDir in $(ls -d */) ; do

echo $myDir

dir_find=$myDir

break

done

}

function getDate()
{
cd $dir_find
chkSpaces

for i in *; do
date=$(ls -ld --time-style=+%Y%m%d $i | cut -d" " -f6)
if  $((10#$date)) -le $((10#$endDate)) ]]; then

    if  $((10#$date)) -ge $((10#$beginDate)) ]]; then

    echo $i >> $logName

    fi
fi
done

}

function chkZero()
{
format=$(echo $1 | grep -e ‘^0[1-9]’)

if  $format ]; then

rightFormat=$1
else
rightFormat=0$1
fi

}

function chkDate()
{
echo
echo -e $bg$b_bold"Please insert the year (YYYY)"$e_bold

read year

if  $year -gt 2009 || $year -lt 1970 ]] ; then

echo "error: year must be between 1970 and 2009. "

exit

fi

echo -e $bg$b_bold"Insert month ...(MM) "$e_bold

read month
if  $month -lt 1 || $month -gt 12 ]]; then
   echo "error: month must be a number between 1 and 12"
   exit
fi

if  $month -lt 10 ]]; then
    chkZero $month
    month=$rightFormat
fi
echo -e $bg$b_bold"Insert the day ...(dd)"$e_bold
read day

if  $day -lt 1 ]]; then
    wrongDay
    exit
fi
case $month in
[11,4,6,9])
    if  $day -gt 30 ]]; then
    wrongDay
fi
;;
2)
if  $day -gt 28 ]];then
    wrongDay
fi
;;
*)
if  $day -gt 31 ]];then
    wrongDay
fi
;;
esac

if  $day -lt 10 ]]; then
chkZero $day
day=$rightFormat
fi

}

function wrongDay()
{
echo "wrong day inserted … " exit
}

function createTar()
{
for i in cat $logName; do
if -f $i ] ; then
tar --append --file=$archName $i
fi
done;
}

clear
selectDir
clear
echo
echo
Now you have to give me two dates, a ‘FROM’ date and a
‘TO’ date. echo Give me them in 3 steps, in the format
YYYY, next MM, and finally dd.

echo I will find every file created in this interval.
echo
The directory is $dir_find
echo
echo -e $b_red"Now insert the ‘FROM’ date"$e_red
chkDate
beginDate=$year$month$day
echo
echo -e $b_red"Now insert the ‘TO’ date"$e_red
chkDate
endDate=$year$month$day
getDate
cat $logName | more
echo
echo
echo “Do you want to create an archive of them? …[y/N]”

echo “(or press a key to quit)”
read create
if $create != “y” ]; then
echo “… bye!”
else
createTar
fi
exit 0

bug :-):

…or press ENTER key

… o anche “or press any key to quit”

Di solito scrivo in dialetto salentino, ma stavolta volevo fare lo chic :smiley:

uh uh uh