Archive Files over certain modification time

Environment is cygwin on Windows Server 2003 as I could not think how I would achieve this using Windows tools.

What I want ot achieve is the following.

I have a Directory D:\Data which contains further subfolders and files. I need to move "files" older than 6 months modification time to E:\Archive\ using the same folder structure.

So using an example of one of the directories:

/cygdrive/d/
/data/
`-- Accounts Dept/
|-- A/
| `--A Prominent Profile Promotions Pty Ltd/
| `anotherfile.doc
`olderthan6mths.txt
`newthan6mths.txt

As you can see there are files under various sub directories. So on the destination I need a way to create the same folder structure for the files older that 6 months to be placed in the same structure like so (assumes the documents anotherfile.doc and olderthan6mths.txt are older that 6 months):

/cygdrive/e/
/Archive/
`-- Accounts Dept/
|-- A/
| `--A Prominent Profile Promotions Pty Ltd/
| `anotherfile.doc
`olderthan6mths.txt

So far I have been able to do this to make the directories but this makes all the directories:

find /cygdrive/d/data/ -type d | xargs -i mkdir -p {} /cygdrive/e/Archive/

And to locate the files older than 6 months, but this would obviusly just move all files into the root of /cygdrive/e/Archive/.

find /cygdrive/d/data/ -mtime +182 -type f | xargs -i mv {} /cygdrive/e/Archive/

So how would I go about creating the directory structure in /cygdrive/e/Archive/ and moving files older than 6 months from /cygdrive/d/data/ whilst preserving there position in the directory structure destination starting at /cygdrive/e/Archive/ from /cygdrive/d/data/?

I have looked and googled by frankly my command line fu is not that good.... yet :slight_smile:

Not sure but.....

I don't believe there's any way to do matching/substitution on {} so I believe what you really need to do is have xargs invoke some script that you write, rather than calling mv, and have your script do the actual mv. That way, you can make substitutions in the path for where you want to move the file to. And, for the directory structure, I would use "mkdir -p" to create the hierarchy. In fact, you could just call it before each move. You only have to give it the path to the final directory and, if necessary, it will create all intermediate sub-directories. If it already exists, then it does nothing.

Draft (untested):

#! /bin/bash

find /cygdrive/d/data/ -mtime +182 -type f >> files.lst

cat files.lst | \
while read SOURCE
do
  TARGET=$( echo $SOURCE | sed 's/d\/data/e\/Archive/' - )
  FOLDER=$( basedir $SOURCE )
  if [ ! -d $FOLDER ]
  then
    mkdir -p $FOLDER
  fi
  mv $SOURCE $TARGET
done

exit 0

dr.house, you Sir are a legend!

I had to make some slight changes to " FOLDER=$( basedir $SOURCE )" to fix it a little but this is what will work. I haven't tested yet with Spaces in the Directory or filenames yet (it is Windows After all) but at least I have a framework to go from now, Awesome!! Thanks to you both for your help so far, i'm very happy with my first post on the forums :slight_smile:

#! /bin/bash

find /cygdrive/d/data/ -mtime +182 -type f >> files.lst

cat files.lst | \
while read SOURCE
do
  TARGET=$( echo $SOURCE | sed 's/d\/data/e\/Archive/' - )
  FOLDER=$( dirname $TARGET )
  if [ ! -d $FOLDER ]
  then
    mkdir -p $FOLDER
  fi
  mv $SOURCE $TARGET
done

exit 0

To make this work as well, you may want to enclose the relevant values and variables in single and double quotes, respectively :wink: