使用某个文件夹下的所有文件去替换另一个文件夹下及其子文件夹下存在的同名文件(Python实现)

值此新年即将到来之际,在这献上今年最后一篇文章.

产生这个需求是在项目的一次图标替换上,当时给了我一堆新图标要替换原来的老图标,可是原来的老图标分布在某个文件夹下的各个子文件夹下面,而新图标全是在同一个目录下的. 手动替换的话,只能是搜索文件名后替换,但是文件很多太麻烦了,没找到现成的工具可以实现我的需求.于是有了下面这个脚本,正好熟悉下刚刚学会的Python. 如果有人知道有什么工具可以完成的话不妨留言告知:).

下面脚本实现的就是在dest目录及其子目录下面,寻找和src目录下的文件对应的同名文件,如果找到唯一的一个同名文件,用src里面的新文件替换dest里面对应的老文件. 如果没找到同名或有多个同名的,就忽略.因为这种情况下需要人工接入是否替换,不过这样工作量已经少了很多了.

 

代码通过扫描一遍dest目录及其子目录,建立了以文件名为索引,文件所在目录名为键值的倒排索引. 然后对src目录下的每个文件名去刚刚建立的倒排索引中寻找键值,如果键值中刚好只有一个目录名,说明找到了对应的唯一同名文件,替换之.其他的忽略.

代码如下:

 

代码
   
     
# !/usr/bin/env python
#
coding:UTF-8

import os,sys,shutil
from os import path

def findandreplace(src,dest):
srcfiles
= os.listdir(src)
destfilesdict
= {}
# 处理目标路径下(含子目录下)的所有文件
for root,dirs,files in os.walk(dest):
# 记录每个文件名所在的路径,多个同名文件则会有多个不同路径.
# 这样就生成了文件名到文件所在路径的一个倒排索引
for onefile in files:
# 若该文件名的键值还未创建则先创建
if onefile not in destfilesdict:
destfilesdict[onefile]
= []
destfilesdict[onefile]
+= [root]
multisamename
= []; # 存储目标目录及其子目录下有多个同名文件的文件名
for srcfile in srcfiles:
fullsrcfile
= os.path.join(src,srcfile)
if os.path.isfile(fullsrcfile):
if srcfile in destfilesdict:
if len(destfilesdict[srcfile]) > 1 :
multisamename
+= [srcfile]
else :
# 有且只有唯一的一个同名文件,那么肯定是要替换的那个
shutil.copy(fullsrcfile,destfilesdict[srcfile][0] + ' / ' + srcfile)
print srcfile + ' replace success. '
print ' following files has more than one in dest directory, replace skipped. '
print ' \n ' .join(multisamename);

if __name__ == " __main__ " :
args
= sys.argv
if len(args) > 2 :
src
= args[ 1 ]
dest
= args[ 2 ]
print " all files under the " + dest + \
" (including the subdirectory) will be replaced by the files under " + \
src
+ " where they have the same name. "
if raw_input( ' Sure(y/n?): ' ) == ' y ' :
findandreplace(src,dest)
else :
print " Not enough arguments! "

 

测试代码如下:

代码
   
     
# !/usr/bin/env python
#
coding:UTF-8

import os,sys
import shutil
import findandreplace

rootdir
= ' d:/test/ '
testsrcdir
= ' testsrc '
testdestdir
= ' testdest '
testfile
= { ' notexist ' : [ ' 001 ' , ' 002 ' , ' 003 ' , ' 004 ' , ' 005 ' ], # 替换目标不存在的文件
' onlyone ' : [ ' 101 ' , ' 102 ' , ' 103 ' , ' 104 ' , ' 105 ' ], # 有唯一对应的文件存在的
' morethanone ' :[ ' 201 ' , ' 202 ' , ' 203 ' , ' 204 ' , ' 205 ' ]} # 多于一个同名存在的
testfileext = ' .txt '
# clear old test files
shutil.rmtree(os.path.join(rootdir,testsrcdir),True)
shutil.rmtree(os.path.join(rootdir,testdestdir),True)
# generate src files
os.makedirs(os.path.join(rootdir,testsrcdir))
for key,values in testfile.iteritems():
for filestr in values:
srcfile
= open(os.path.join(rootdir,testsrcdir,filestr + testfileext), ' w ' )
srcfile.write(filestr
+ ' srcfile ' )
srcfile.close()
# generate dest files
os.makedirs(os.path.join(rootdir,testdestdir))
for key,values in testfile.iteritems():
if key == ' notexist ' :
pass
elif key == ' onlyone ' :
for filestr in values:
newdir
= os.path.join(rootdir,testdestdir,filestr)
os.makedirs(newdir)
srcfile
= open(os.path.join(newdir,filestr + testfileext), ' w ' )
srcfile.write(filestr
+ ' destfile ' )
srcfile.close()
elif key == ' morethanone ' :
for filestr in values:
newdir
= os.path.join(rootdir,testdestdir,filestr)
os.makedirs(newdir)
srcfile
= open(os.path.join(newdir,filestr + testfileext), ' w ' )
srcfile.write(filestr
+ ' destfile ' )
srcfile.close()
srcfile
= open(os.path.join(rootdir,testdestdir,filestr + testfileext), ' w ' )
srcfile.write(filestr
+ ' destfile ' )
srcfile.close()

findandreplace.findandreplace(os.path.join(rootdir,testsrcdir),os.path.join(rootdir,testdestdir))

 

Python真是提高效率的利器哈.

 

你可能感兴趣的:(python)