【问题标题】:Easy way of moving directories containing old files away移动包含旧文件的目录的简单方法
【发布时间】:2012-03-27 17:20:51
【问题描述】:

我在 /home/customers/customer1、/home/customers/customer2 等路径中维护了很多(约 1000 个)客户文件夹。现在客户来来去去,我不想保留在我的工作驱动器中一段时间​​(例如 2 年)未修改的文件夹。

我需要的是一个简单的脚本

a) 立即获取所有候选文件夹(即不递归到子文件夹,因为我不想拆分客户的数据)给定路径的后代(例如 /home/customers/);

b) 为每个文件夹计算最近的修改时间;

c) 如果某个文件夹(例如 /home/customers/mycustomer231)的修改时间早于 1 年,请将其移动到指定路径(例如 /var/backup/oldcustomers)。

实现它的最简单方法是什么?

用什么语言?在巴什?珀尔? Python?其他语言?

我知道一些 Bash 的基础知识。我知道,有一种方法可以通过将find <..> -exec 嵌套在另一个find <..> -exec 中并使用this thread 的建议来实现它,但是生成的代码肯定看起来不容易理解和维护。 我也知道其他提到的语言的一些基础知识,足以理解他们的大部分代码,但没有足够的经验来编写我自己的解决方案。

(是的,我可以花一个月以上的时间学习其中一种语言,但是要解决我孤立的问题,时间成本太高了。我敢肯定,问题是基本的,而且专业的人很多/home/ 中的用户并正在清除旧条目,已经有解决方案。)

【问题讨论】:

  • 我认为使用这三种语言中的任何一种都可以轻松完成这项工作。

标签: python perl bash scripting


【解决方案1】:

要查找 365 天前修改的所有目录:

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

要将它们移动到新位置:

$ find /home/customers -maxdepth 1 -type d -mtime +365 -exec mv {} /var/backup/oldcustomers \;

【讨论】:

    【解决方案2】:

    与使用 find + xargs 的 bash 单行程序相比,完全过度设计,但这里有一个快速的 Python 脚本,部分是从我之前编写的其他一些脚本中混搭而来的。应该可以很好地满足您的目的。

    现在我努力的唯一原因是因为你发表的评论:

    是的,我可以花一个月以上的时间学习其中一种语言

    值得付出努力,并且很快就会得到回报。 这个脚本花了大约 7 分钟,包括做一些测试。

    #!/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)
    

    只需将其放入 PATH 中的某个文件(如 move_old_dirs)中,chmod 即可执行并试一试。

    【讨论】:

      【解决方案3】:

      你可以使用find:

      find /home/customers -maxdepth 1 -type d -mtime +365 -exec mv '{}' /var/backup/oldcustomers/ \;
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-11-13
        • 1970-01-01
        • 1970-01-01
        • 2017-05-06
        • 1970-01-01
        • 2014-01-16
        相关资源
        最近更新 更多