Move all files from dir and subdir to Archive with File name as complete path_filename

HI,

I need to move all files from a dir & its all subdir to Archive folder which is indise dir only. and moved filename should changed to complete path ( Like Dir_subdir_subdir2_.._filename ). also all files names shoud capture in a file in order to mail

I written below code

filetime()
{
        perl  -e '@d=localtime ((stat(shift))[9]); printf "%4d%02d%02d%02d%02d%02d\n", $d[5]+1900,$d[4]+1,$d[3],$d[2],$d[1],$d[0]' "$1"
}
und="_"
count="0"
FFile="/export/home/srcdata1/tTemp"
Flist="$FFile/Filelist"
Ftemp="$FFile/temp"
#$count -eq 0
for int in `ls -l $FFile | grep ^d | awk '{print $9}'`
do
arch="$FFile/Archived"
if [ ! -d arch ]; then
   echo " *******  not inside Arch and also  not in Organised ***** -----*"
   #echo `ls |wc -l`
   find $FFile -type f| awk 'BEGIN{FS="/"} {print $NF}' > $Flist
   while read line
                do
   #echo "  inside while read line "
                        if [ -e $FFile/"$line" ]; then
                                ftime=$(filetime $FFile/"$line" )
                                yyyy=`echo $ftime | cut -c 1-4`
                                mm=`echo $ftime | cut -c 5-6`
                                dd=`echo $ftime | cut -c 7-8`
                                echo "  Added time stamp to file name "
                        else
                                continue
                        fi
     monyyyy=${yyyy}${und}${mm}
                        if [ ! -d $arch/$int$monyyyy ]; then
                        mkdir $arch/$int$monyyyy
                        fi
                        echo $FFile/$int/"$line"
                        echo $arch/$int/$monyyyy/"$line"
                        mv $FFile/$int $arch/$int$monyyyy

   done < $Flist
  # echo " -----------   moved to archived now check ------------"
fi
done

My code is moving just the FileLIst ( which contains name of all files) not the files. Also how can i prefix filename before moving to folder with time stamp of file created

You seem to have be solving a simple problem in a complicated way. Can you not just use tar?

tar cf $arch/$monyyyy.tar $FFile

creates a tar file in the "$arch" directory with your derived time stamp on it (which I would get using `date +%m%Y` ) and all the files underneath "$FFile"

Do you really need something more complicated?

Hi,

Thanks for your help.
But my requirement is I need to moves files with full path + date & time of the file created not the sysdate time

The tar program saves the time attributes of the files it archives.

hi,

can any 1 help me with getting file creation time as the renamed file?
rest of the things are working.

but i need

dir1-->f1 ( time of creation of file can get by ls -lrt)
mv f1 dir1/archived/f1_time_of_file_creation

please help me with this.

I don't understand why you use a perl script just to get the mtime from the file you want to move. Why not just do the whole thing in perl? I have no idea what $int is supposed to mean. I also don't understand why you use the perl script to output the time in a format that you then have to parse with 3 separate invocations. Here's a more logical alternative:

filetime() {
   # Change %F,%T as needed. See "man strftime"
   perl  -mPOSIX -e 'print POSIX::strftime("%F,%T\n",localtime((stat(shift))[9]))' ; 
}

while read line ; do 
        test ! -e "$FFile/$line" && continue;

        monyyyy=$(filetime "$FFile/$line")
        mkdir -p $arch/$line
        mv "$FFile/$line" $arch/$line/$monyyyy
done

But I think this entire approach could be simplified with using GNU's fileutils' find:

$adir=ARCHIVE_DIR
$sdir=SOURCE_DIR
$flist=/tmp/filelist.$$
# Step 1: Create the list of files
cd $sdir
find . -type f -printf "%T+ %p\n" > $flist

# Step 2: create the directory tree in adir
cd $adir
awk '{ print $2 }' $flist | xargs $DEBUG mkdir -p 

# Step 3: move the files
cd $sdir
cat $flist | 
while read time path ; do
   $DEBUG mv $path $adir/$path/$time
done

To prevent this from destroying files while you test, export DEBUG=echo

Useless Use of Cat

You could just do

...

while read time path ; do
   $DEBUG mv $path $adir/$path/$time
done <$flist

Of course.... I'm trying to be instructional. :stuck_out_tongue:

hi Thanks for your help. But

find . -type f -printf "%T+ %p\n" this is not working in my unix 
find: bad option -printf
find: path-list predicate-list

this error is coming.

For finding time I tried this also

find . -type f --time 

again --time is not supoorted by my unix.

yeah you need GNU's find. Ask your admin to install it

Hi both,

thanks a lot for your help. I am very near to solve my problem but as sugessted by you i am trying to use this -

find . -type f -printf "%T+ %p\n"

but my unix says -printf is unknown i tried same with -print then it says %T %p are bad options.

Also i tried to use while loop with time and path but it is not fetching time & path into it.

I am using ksh. Please let me know if you required some more info about mu unix.

Thanks.

In my solution, you need to use GNU's find. You can replace it, however, with a perl script:

find . -type f -print | perl -mPOSIX -ne 'chop;$t = (stat($_))[9]; 
  print POSIX::strftime("%F+%T ",localtime($t)).$_."\n"'

So it's just using the traditional find command (perl can do this, but it's uglier) to feed into perl, which for each filename (reading from stdin) gets the time's filestamp ($t) and prints it out in the same format as GNU's %T+, followed by a space and the filename and the newline.