1

I maintain a lot (ca 1000) of customers' folders in paths /home/customers/customer1, /home/customers/customer2,... etc. Now customers come and go, and I don't want to keep folders which were not modified for some time (e.g. 2 years) in my working drive.

What I need, is a simple script that would

a) take all candidate folders as immediate (i.e. without recursion to sub-folders, as I don't want to split customer's data) descendants of a given path (e.g. /home/customers/);

b) for each folder compute the most recent modification time;

c) if the modification time for some folder (e.g. /home/customers/mycustomer231) is older than, say, 1 year, move it to specified path (e.g. /var/backup/oldcustomers).

What is the simplest way of implementing it?

In what language? In Bash? Perl? Python? Some other language?

I know some basics of Bash. I know, that there is a way of achieving it by nesting one find <..> -exec inside another and using advice from this thread, but the resulting code surely would not look easy to understand and maintain. I also know some basics of the other mentioned languages, enough to understand most of their code, but without enough experience to write my own solution.

(Yes, I could spend month+ learning one of those languages, but for solving my isolated problem the price in time is too dear. I'm sure, that the problem is basic and people who professionaly work with lot of users in /home/ and were purging old entries, already have solution for it.)

Community
  • 1
  • 1
Adam Ryczkowski
  • 7,592
  • 13
  • 42
  • 68

3 Answers3

1

To find all directories modified 365 days ago:

$ find /home/customers -maxdepth 1 -type d -mtime +365 -exec stat -c '%y %n' {} \;

To move them to a new place:

$ find /home/customers -maxdepth 1 -type d -mtime +365 -exec mv {} /var/backup/oldcustomers \;
kev
  • 155,172
  • 47
  • 273
  • 272
0

You could use find:

find /home/customers -maxdepth 1 -type d -mtime +365 -exec mv '{}' /var/backup/oldcustomers/ \;
sgibb
  • 25,396
  • 3
  • 68
  • 74
0

Completely overengineered compared to a bash one liner using find + xargs, but here is a quick python script, partly mashed up from some other scripts I had written before. Should work quite well for your purposes.

Now the only reason I went to the effort is because of that comment you made:

Yes, I could spend month+ learning one of those languages

Its well worth the effort, and will pay itself off very quickly. This script took about 7 minutes including doing some tests.

#!/usr/bin/python
import datetime
import os
import sys
import shutil

SOURCE_PATH = "/home/customers/"
TARGET_PATH = "/home/oldcustomers/"
TIME_THRESHOLD = datetime.timedelta(365)    #days

def get_old_dirs(source_path, time_threshold):
    old_dirs = []
    for root, dirs, files in os.walk(source_path):
        for d in dirs:
            full_path = os.path.join(root, d)
            now = datetime.datetime.now()
            last_modified = datetime.datetime.fromtimestamp(os.stat(full_path).st_mtime)
            delta = now - last_modified
            if (delta) >= time_threshold:
                old_dirs.append((full_path, delta))
        break
    return old_dirs

def move_old_dirs(target_path, source_path, time_threshold, confirm=True):
    dirs = get_old_dirs(source_path, time_threshold)
    print '"old" dirs: %d' % len(dirs)
    if dirs:
        if confirm:
            print "pending moves:"
            for (d, delta) in dirs:
                print "[%s days] %s" % (str(delta.days).rjust(4), d)
            if not raw_input("Move %d directories to %s ? [y/n]: " % (len(dirs), target_path)).lower() in ['y', 'yes']:
                return
        if not os.path.exists(target_path):
            os.makedirs(target_path)
        for (d, delta) in dirs:
            shutil.move(d, target_path)
            print "%s -> %s" % (d, target_path)
        print "moved %d directories" % len(dirs)


def cmdline(args):
    from optparse import OptionParser
    usage = "move_old_dirs [options] <source_dir> <target_dir>"
    default_desc = "%s -> %s [%s]" % (SOURCE_PATH, TARGET_PATH, TIME_THRESHOLD)
    parser = OptionParser(usage)
    parser.add_option("-d", "--days",
                      action="store", type="int", dest="days", default=365,
                      help="How many days old the directory must be to move")
    parser.add_option("--default", default=False,
                    action="store_true", dest="default", 
                    help="Run the default values set in the script: (%s)" % default_desc)   
    parser.add_option("-f", "--force", default=False,
                    action="store_true", dest="force", 
                    help="Dont ask for confirmation")   
    (options, args) = parser.parse_args(args)
    if len(args) == 1 and options.default:
        print "running default: %s" % default_desc
        return move_old_dirs(TARGET_PATH, SOURCE_PATH, TIME_THRESHOLD, confirm=(not options.force))
    elif len(args) == 3:
        return move_old_dirs(args[2], args[1], datetime.timedelta(options.days), confirm=(not options.force))
    print usage
    print "incorrect number of arguments, try -h or --help"
    return 1

if __name__ == "__main__":
    cmdline(sys.argv)

just chuck that in some file (like move_old_dirs) in PATH, chmod to executable and have a go.

Preet Kukreti
  • 8,417
  • 28
  • 36