免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
12下一页
最近访问板块 发新帖
查看: 10580 | 回复: 14
打印 上一主题 下一主题

本人编写的第一个脚本,用来删除所有旧版本文件和空文件夹,恳请高手给出意见。 [复制链接]

论坛徽章:
4
金牛座
日期:2013-10-11 16:12:50卯兔
日期:2014-07-31 09:17:19辰龙
日期:2014-08-08 09:28:02狮子座
日期:2014-09-14 20:32:05
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2012-06-30 18:30 |只看该作者 |倒序浏览
本帖最后由 ssfjhh 于 2012-07-02 19:52 编辑




为什么CU发代码的这个<>会吃代码?

比如正则表达式我明明写的是<'\.\d+$'>

发出来以后却变成了<'\.\d+>,<$'>被吃掉了,

导致贴出的代码无法正常运行。






我经常要用proe工作,这个软件在保存的时候每次都会生产一个带有新版本号的文件,形如
abc.asm.13', 'abc.asm.14', 'abc.asm.2', 'abc.asm.3', 'abc.asm.4', 'abc.asm.5', 'abc.asm.6', 'abc.log.8', 'abc.log.9', 'abc.prt.1', 'abc.prt.10', 'abc.prt.11', 'abc.prt.12', 'abc.prt.13', 'abc.prt.14', 'abc.prt.2', 'abc.prt.3', 'abc.prt.4', 'abc.prt.5', 'abc.prt.6', 'abc.prt.7', 'abc.prt.8', 'abc.prt.9',

但是这目录下还会有其他文件夹和一些不带版本号的文件,如 'abc0', 'abc1', 'abc1.doc', 'abc1.dwg', 'abc1.dxf',

我写的这个脚本用来删除脚本所在目录以及子目录下所有旧版本的文件以及空目录,并将最新版的的文件的版本号改为1,不带版本号的文件不做处理
但是总感觉在判断旧版本的地方写得很不好,又想不出更好的办法,恳请高手给出意见,算法上的和代码编写习惯上的,只要你能给出的意见都可以因为是第一次写代码,所以脚本中尽可能多的用上了自己所掌握的技能。

代码如下:
  1. def name(filename):
  2.     """输入一个文件名,如果带版本号就去掉版本号,如果不带版本号,原样返回"""
  3.     import re
  4.     return re.sub('\.\d+,'', filename)


  5. def version(filename):
  6.     """返回给出带版本号的文件名的版本号"""
  7.     import re
  8.     return re.sub('^.+\..+\.(?=\d+$)', '', filename)


  9. def chverto1(currentdir, filename):
  10.     """将输入的版本号不为1的文件名的版本号改为1"""
  11.     import os
  12.     if version(filename) == '1':
  13.         print("文件\"{}\"的最新版本为1,不需要处理".format(os.path.join(currentdir,filename)))
  14.     else:
  15.         oldpathname = os.path.join(currentdir, filename)
  16.         newpathname = os.path.join(currentdir,  name(filename) + '.1')
  17.         print("文件\"{}\"的版本号被改为1".format(oldpathname))
  18.         if os.path.exists(newpathname):
  19.             print('正在删除旧版文件' + "\"" +newpathname +"\"")
  20.             os.remove(newpathname)
  21.         os.rename(oldpathname, newpathname)


  22. def isversionfile(filename):
  23.     """判断给出的文件名是否带版本号"""
  24.     import re
  25.     if re.search('\.\d+,filename) != None:
  26.         return True
  27.     else:
  28.         return False


  29. def sortfile(currentdir):
  30.     """分类给出的目录,返回一个二维列表,第一个是子目录列表,第二个是带版本号文件名列表"""
  31.     import os
  32.     dirlist = []
  33.     versionfilelist = []
  34.     allfile = [dirlist, versionfilelist]
  35.     unsortedfilelist = os.listdir(currentdir)
  36.     print('开始分类文件夹\"' + currentdir + "\"")
  37.     for i in unsortedfilelist:
  38.         if os.path.isdir(os.path.join(currentdir,i)):
  39.             dirlist.append(i)
  40.         elif isversionfile(i):
  41.             versionfilelist.append(i)
  42.         else:
  43.             print("文件\"{}\"不是带版号的文件,不需要处理".format(os.path.join(currentdir, i)))
  44.     else:
  45.         return allfile


  46. def delfiles(currentdir, versionfilelist):
  47.     """输入一个目录和一个带版本号的文件名列表,删除所有旧版本,并将最新版的版本号改为1"""
  48.     import os
  49.     filecutverset = {name(i) for i in versionfilelist}
  50.     for i in filecutverset:
  51.         allversionofafile = []
  52.         for j in versionfilelist:
  53.             if i == name(j):
  54.                 allversionofafile.append(j)
  55.         #判断不带版本号部分的文件名部分是否与已知的去掉版本部分是否一直得到一个文件的所有版本
  56.         else:
  57.             allversionofafile.sort()
  58.             latestversionname = allversionofafile.pop()
  59.         #排序同文件的不同版本,最新的版本版本号最大,处于序列的最末位置,
  60.         #使用pop()取出最新版本文件名备用,列表中剩下的全为旧版本,应该删除
  61.         #使用else语句,可以保证循环部分没有错误才会执行排序
  62.         for k in allversionofafile:
  63.             print('正在删除旧版文件' + "\"" +os.path.join(currentdir,k) +"\"")
  64.             os.remove(os.path.join(currentdir,k))
  65.         else:
  66.             chverto1(currentdir, latestversionname)
  67.         #删除列表中的所有旧文件,使用else语句,保证删除过程没有错误才会执行重命操作



  68. def rmof(currentdir):
  69.     """看了这么多函数,都是为这个函数服务滴"""
  70.     import os
  71.     print("准备清理文件夹\"" + currentdir + "\"下的旧版本文件")

  72.     if os.listdir(currentdir) == []:
  73.         os.rmdir(currentdir)
  74.         print("文件夹\"{}\"是空文件夹,删除".format(currentdir))
  75.         return None
  76.     else:
  77.         dirlist, versionfilelist = sortfile(currentdir)
  78.     #首先判断目录是否为空,避免进行不必要的操作,空目录留着何用呢,亮不犹豫的,删掉
  79.    
  80.     if versionfilelist == []:
  81.         pass
  82.     else:
  83.         delfiles(currentdir, versionfilelist)
  84.     #判断文件夹下是否有带版本号的文件名,有才需要进一步操作撒,没有直接pass
  85.    
  86.     for i in dirlist:
  87.         print("进入文件夹\"{}\"下的子文件夹\"{}\"".format(currentdir,i))
  88.         rmof(os.path.join(currentdir,i))
  89.     #for循环本身就有判断作用,不需要现多作用if做判断了
  90.     #如果存在子目录,递规调用自身,删除目录下的所有文件不费力,递规真好用呀
  91.         
  92.     if os.listdir(currentdir) == []:
  93.         os.rmdir(currentdir)
  94.         print("文件夹\"{}\"是空文件夹,删除".format(currentdir))
  95.     #再做一次判断,避免当前目录下只有子目录,没有子文件,
  96.     #而子目录又都是空目录,递规删除子目录后,父目录也变为空的极少情况发生,谁让咱有洁癖呢
  97.         

  98. def countdown(t):
  99.     import time
  100.     while t:
  101.             print(str(t) + ' ', end = '')
  102.             t= t-1
  103.             time.sleep(1)
  104.     #计个数,谁能告诉我怎么实现数字在一个地方跳动的效果,貌似这个\b不行呀


  105. def comfirm():
  106.     """一次要删这么多文件,本着负任的态度,必须得问问清楚用户是否真的要这么干

  107.     好吧,我承认,我是怕我自己误操作才写这么一段函数的"""
  108.     import os,sys,time
  109.     currentdir = sys.path[0]
  110.     #脚本有可能被转成exe,如果被转成exe,上边这句该怎么写
  111.     #我保证,你告诉我之后我就能写出脚本和exe都能正确执行的语句
  112.     """\
  113. 确定要清理文件夹\"{}\"吗?
  114. 本脚本将会删除所有该文件夹下的旧版本文件以及空文件夹,删除操作不可恢复!!!
  115. """
  116.     print("确定要清理文件夹\"{}\"吗?\n本脚本将会删除所有该文件夹下的旧版本文件以及空文件夹,删除操作不可恢复!!!".format(currentdir))
  117.     trytimes = 3
  118.     while trytimes:
  119.         trytimes = trytimes -1
  120.         getinput = input("确认操作请输入‘yes', 取消请输入'no':")
  121.         if getinput == 'yes':
  122.             rmof(currentdir)
  123.             print("所有旧友版文件都已被删除,请检查!")
  124.             input('按回车键退出')
  125.             break
  126.         elif getinput == 'no':
  127.             print("操作已取消,5秒种后退出", end = '')
  128.             countdown(5)
  129.             break
  130.         elif trytimes >= 1:
  131.             print('yes or no, please!')
  132.             print("还有{}次机会".format(trytimes,))
  133.     else:
  134.         print("错误次数太多,操作取消,10秒种后退出",end = '')
  135.         countdown(10)
  136.             

  137. comfirm()
复制代码

论坛徽章:
4
金牛座
日期:2013-10-11 16:12:50卯兔
日期:2014-07-31 09:17:19辰龙
日期:2014-08-08 09:28:02狮子座
日期:2014-09-14 20:32:05
2 [报告]
发表于 2012-06-30 18:36 |只看该作者
怎样才能插入代码,我看到别人都能插入比较漂亮的代码,如下所示

论坛徽章:
2
CU大牛徽章
日期:2013-04-17 11:46:28CU大牛徽章
日期:2013-04-17 11:46:39
3 [报告]
发表于 2012-06-30 18:41 |只看该作者
回复 2# ssfjhh


    选中所有代码,点击回复框上面的”<>“按钮即可

论坛徽章:
4
金牛座
日期:2013-10-11 16:12:50卯兔
日期:2014-07-31 09:17:19辰龙
日期:2014-08-08 09:28:02狮子座
日期:2014-09-14 20:32:05
4 [报告]
发表于 2012-06-30 18:59 |只看该作者
回复 3# cdtits

3q,已经改好了。

   

论坛徽章:
2
CU大牛徽章
日期:2013-04-17 11:46:28CU大牛徽章
日期:2013-04-17 11:46:39
5 [报告]
发表于 2012-06-30 19:56 |只看该作者

  1. def CountDown(t):
  2.     import time
  3.     mlen = len(str(t)) + 1
  4.     blank = '\b \b' * mlen + '%d'
  5.     print t,
  6.     while t:
  7.         time.sleep(1)
  8.         t -= 1
  9.         print blank % t,

  10. if __name__ == '__main__':

  11.     CountDown(100)
复制代码

论坛徽章:
0
6 [报告]
发表于 2012-07-02 13:52 |只看该作者
本帖最后由 xtdumpling 于 2012-07-02 14:11 编辑

python 2.6的版本,3.0以上需要把raw_input 改为input
  1. #-*- coding:utf-8 -*-

  2. import os
  3. import sys
  4. import re

  5. class delmass(object):
  6.     def __init__(self, workdir = os.curdir):
  7.         self.workdir = os.path.abspath(workdir)
  8.         self.flist = [f for f in os.listdir(self.workdir) if os.path.isfile(f)]
  9.         self.dlist = [d for d in os.listdir(self.workdir) if os.path.isdir(d)]

  10.     def delfiles(self):
  11.         # filename end with dot+digital, such as abcd.efgx.1234
  12.         pattern = '\w+\.\w+\.\d+'
  13.         for eachfile in self.flist:
  14.             if re.match(pattern, eachfile):
  15.                 print 'Remove file:', eachfile
  16.                 os.unlink(eachfile)

  17.     def deldirs(self):
  18.         for eachdir in self.dlist:
  19.             if os.listdir(eachdir) == []:
  20.                 print 'Remove dir:', eachdir
  21.                 os.rmdir(eachdir)

  22. def main():
  23.     '''删除目标文件夹里面带版本号的文件和空文件夹,目标文件夹可以作为参数或者默认是当前文件夹'''
  24.     if len(sys.argv) > 1:
  25.         dm = delmass(sys.argv[1])
  26.     else:
  27.         dm = delmass()

  28.     print u"确认操作请输入‘yes', 取消请输入'no':",
  29.     if raw_input().strip() == 'yes':
  30.         dm.delfiles()
  31.         dm.deldirs()
  32.     else:
  33.         print u'操作已取消'

  34. if __name__ == '__main__':
  35.     main()
复制代码

论坛徽章:
4
金牛座
日期:2013-10-11 16:12:50卯兔
日期:2014-07-31 09:17:19辰龙
日期:2014-08-08 09:28:02狮子座
日期:2014-09-14 20:32:05
7 [报告]
发表于 2012-07-02 14:56 |只看该作者
本帖最后由 ssfjhh 于 2012-07-02 14:58 编辑

回复 6# xtdumpling
  1. def delfiles(self):
  2.         # filename end with dot+digital, such as abcd.efgx.1234
  3.         pattern = '\w+\.\w+\.\d+'
  4.         for eachfile in self.flist:
  5.             if re.match(pattern, eachfile):
  6.                 print 'Remove file:', eachfile
  7.                 os.unlink(eachfile)
复制代码
你这段代码的意思应该是删掉所有带版本号的文件,这个是不符合我的要求的。

我需要的功能是,假如文件夹下有abcd.efgx.1234,abcd.efgx.1235,abcd.efgx.1246三个文件,删掉abcd.efgx.1234,abcd.efgx.1235,并将abcd.efgx.1246改为abcd.efgx.1
而且要实现递规操作,删除,所有子目录中的旧版文件。

不过,你的代码比我的简洁太多了,用到了类,我还不会用。

非常感谢。

论坛徽章:
0
8 [报告]
发表于 2012-07-03 15:02 |只看该作者
本帖最后由 xtdumpling 于 2012-07-03 15:09 编辑

我也是刚刚开始学习,把书上的知识尝试一下。
改进一下:
  1. #!/usr/bin/env python
  2. #-*- coding:utf-8 -*-

  3. import os
  4. import sys
  5. import re

  6. class delmass(object):
  7.     def __init__(self, workdir = os.getcwd()):
  8.         self.orgdir = os.getcwd()
  9.         self.workdir = os.path.abspath(workdir)
  10.         os.chdir(self.workdir)
  11.         self.lastfiles = {}

  12.     def _getlatestfiles(self, fname, fversion):
  13.         #get all last file name
  14.         if fname in self.lastfiles:
  15.             if int(fversion) > int(self.lastfiles[fname]):
  16.                 print 'Remove file: %s%s' %(fname, self.lastfiles[fname])
  17.                 os.unlink('%s%s' %(fname,self.lastfiles[fname]))
  18.                 self.lastfiles[fname] = fversion
  19.             else:
  20.                 print 'Remove file: %s%s' %(fname, fversion)
  21.                 os.unlink('%s%s' %(fname,fversion))
  22.         else:
  23.             self.lastfiles[fname] = fversion

  24.     def _delfiles(self):
  25.         # handle filename end with dot+digital, such as abcd.efgx.1234
  26.         self.flist = [f for f in os.listdir(self.workdir) if os.path.isfile(f)]
  27.         pattern = '(\w+\.\w+\.)(\d+)'
  28.         for eachfile in self.flist:
  29.             m = re.match(pattern, eachfile)
  30.             if m:
  31.                 print 'found file: %s%s' %(m.group(1), m.group(2))
  32.                 self._getlatestfiles(m.group(1), m.group(2))
  33.         else:
  34.             # change all last files' version to 1
  35.             for fname in self.lastfiles:
  36.                 os.rename('%s%s' %(fname,self.lastfiles[fname]), \
  37.                           '%s%s' %(fname,'1'))

  38.     def _deldirs(self):
  39.         # remove all empty dirs
  40.         self.dlist = [d for d in os.listdir(self.workdir) if os.path.isdir(d)]
  41.         for eachdir in self.dlist:
  42.             if os.listdir(os.path.abspath(eachdir)) == []:
  43.                 print 'Remove dir:', os.path.abspath(eachdir)
  44.                 os.rmdir(eachdir)
  45.             else:
  46.                 # self class recursion for sub dir
  47.                 print 'handle dir:', os.path.abspath(eachdir)
  48.                 delmass(eachdir).delall()

  49.     def delall(self):
  50.         self._delfiles()
  51.         self._deldirs()

  52.     def __del__(self):
  53.         # restore to original dir
  54.         os.chdir(os.path.abspath(self.orgdir))

  55. def main():
  56.     '''删除目标文件夹里面带版本号的文件和空文件夹,目标文件夹可以作为参数或者默认是当前文件夹'''
  57.     if len(sys.argv) > 1:
  58.         dm = delmass(sys.argv[1])
  59.     else:
  60.         dm = delmass(os.curdir);

  61.     print u"确认操作请输入‘yes', 取消请输入'no':",
  62.     if raw_input().strip() == 'yes':
  63.         dm.delall()
  64.     else:
  65.         print u'操作已取消'

  66. if __name__ == '__main__':
  67.     main()
复制代码

论坛徽章:
4
金牛座
日期:2013-10-11 16:12:50卯兔
日期:2014-07-31 09:17:19辰龙
日期:2014-08-08 09:28:02狮子座
日期:2014-09-14 20:32:05
9 [报告]
发表于 2012-07-04 12:12 |只看该作者
感谢,比我的代码精简多了,

def _getlatestfiles(self, fname, fversion):这部分里边出现了
os.unlink('%s%s' %(fname,self.lastfiles[fname]))
os.unlink('%s%s' %(fname,fversion))
都是不带路径的文件名,能正确运行吗?

论坛徽章:
0
10 [报告]
发表于 2012-07-04 13:51 |只看该作者
删除的文件都是在当前目录,我测试过可以的。
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP