python实现既定后缀名的文件移动
"""
问题描述:
输入文件夹路径,设定文件后缀要求,筛选文件移动到待保存文件路径。需保证筛选文件依然保留文件夹的子目录关系。
输入文件夹路径:r"C:\Users\deng\Desktop\kpi";
后缀名筛选:[txt,xlsx,bmp];
保存文件路径:"F:\xxxx\123\sample"
ex:
符合条件的文件:C:\Users\deng\Desktop\kpi\2\3\ni.txt
需要保存到:F:\xxxx\123\sample\kpi\2\3\ni.txt
"""
import os
import shutil
import traceback
def filterfile(file_dir,save_dir,suffix):
outsidefile=[]
outsiderfolder=[]
path=os.listdir(file_dir)
print(path)
#['1', '2', 'plan.txt'],只返回文件夹和文件的name
for i in path:
if os.path.isfile(file_dir+"\\"+i):
outsidefile.append(file_dir+"\\"+i)
elif os.path.isdir(file_dir+"\\"+i):
outsiderfolder.append(file_dir+"\\"+i)
print(outsidefile,outsiderfolder)
#['C:\\Users\\deng\\Desktop\\kpi\\plan.txt'] ['C:\\Users\\deng\\Desktop\\kpi\\1', 'C:\\Users\\deng\\Desktop\\kpi\\2']
if len(outsidefile)!=0:
for file in outsidefile:
file_type = file.split(".")[-1] # 返回后缀名
outsidefileheadpath=file.split("\\")[-2]
if (file_type in suffix): # 后缀名属于suffix内
isExists=os.path.exists(save_dir+"\\"+outsidefileheadpath)
if not isExists:
os.makedirs(save_dir+"\\"+outsidefileheadpath)
print("文件夹创建成功")
else:
print("文件夹已经创建了")
shutil.copy(file,save_dir+"\\"+outsidefileheadpath)
#接下来对文件夹进行第二层的处理,
for inside in outsiderfolder:
insiderfile=[]
insiderfolder=[]
path1=os.listdir(inside)
print(path1)
for j in path1:
if os.path.isfile(inside+"\\"+j):
insiderfile.append(inside+"\\"+j)
elif os.path.isdir(inside+"\\"+j):
insiderfolder.append(inside+"\\"+j)
print(insiderfile, insiderfolder)
if len(insiderfile)!=0:
for file in insiderfile:
file_type = file.split(".")[-1] # 返回后缀名,1\\abc.cpp
file_headpath=file.split("\\")[-2]
file_headheadpath=file.split("\\")[-3]
if (file_type in suffix): # 后缀名属于suffix内
isExists = os.path.exists(save_dir + "\\"+file_headpath)
if not isExists:
os.makedirs(save_dir + "\\" + file_headpath)
print("文件夹创建成功")
else:
print("文件夹已经创建了")
shutil.copy(file, save_dir + "\\" +file_headpath)
for file in insiderfolder:
filetype=file.split(".")[-1]
fileheadpath=file.split("\\")[-2]
if(filetype in suffix):
isExists = os.path.exists(save_dir + "\\" + fileheadpath)
if not isExists:
os.makedirs(save_dir + "\\" + fileheadpath)
print("文件夹创建成功")
else:
print("文件夹已经创建了")
shutil.copy(file,save_dir+"\\"+fileheadpath)
if __name__ == "__main__":
filterfile(r"C:\Users\deng\Desktop\kpi",r"D:\sample",["txt"])
代码demo1,对文件操作的理解在于用列表来进行一层、两层深度的操作,在写代码过程十分冗杂且繁琐,不符合计算机编程思维。
此demo1只适合文件夹只有一两层的子文件目录,且子文件夹同级没有文件,抽象不足。
import os
import shutil
import traceback
def filterfile(file_dir,save_dir, suffix):
filelist = [] #符合后缀要求的文件
for dirpath, dirnames, filenames in os.walk(file_dir):#遍历
for file in filenames:
file_type = file.split(".")[-1] # 返回后缀名
dirnames = ",".join('%s' % id for id in dirnames)
if (file_type in suffix): # 后缀名属于suffix内
file_fullpath = os.path.join(dirpath, dirnames, file)#file的绝对路径
filelist.append(file_fullpath)
for file in filelist:
headpath, filename=os.path.split(file)#headpath为上级路径,filename为文件夹名字
print(headpath,filename)#F:\first\kpi\1\sample 123.xlsx
headpath_filename,headfile=os.path.split(headpath)
isExists = os.path.exists(save_dir + "\\" + headfile)
print(isExists)
if not isExists:
os.makedirs(save_dir + "\\" + headfile)
print("文件夹创建成功")
else:
print("文件夹已经创建了")
shutil.copy(file, save_dir + "\\" + headfile)
def test():
try:
return 1 / 0
except Exception as e:
# 默认在终端打印异常信息, 默认色彩是红色
traceback.print_exc()
# 使用变量接收错误信息
err = traceback.format_exc()
print(err) # 使用print打印将不具备色彩
return 0
if __name__ == "__main__":
print("此脚本对单个文件夹内的N个子文件夹中的文件进行遍历,通过后缀名的筛选把符合条件的文件复制到指定文件夹中")
print("请输入你的文件夹所在位置,如r'F:\pentakill\kpi'")
file_dir=input()
print("请输入筛选文件保存位置:如'E:\个人文件\筛选文件'")
save_dir=input()
print('请输入符合文件筛选的后缀名:\n\t需打英文双引号,如"xlsx","txt","bmp"')
suffix=input()
filterfile(file_dir,save_dir,suffix)
input("程序运行完成。")
print(test())
代码demo2,对文件和子目录的关系是靠split函数、join函数来拼接、拆分,考虑的是子目录在列表中的相对位置。但是若子文件夹中既有文件,又有文件夹,将会导致筛选不完全,这是第二次demo写的缺陷,对于文件夹内文件和子目录复杂的情况下依然不能满足。
import shutil
import os
def filecopy(url,save_dir,suffix):
listfile=[]#符合条件的文件list
listfilepath=[]#文件夹list
for filepath, dirnames, filenames in os.walk(url):
for filename in filenames:
if filename.split(".")[-1] in suffix:#符合后缀
real_path=os.path.join(filepath,filename)#真实路径,将目录和文件和在一起
listfile.append(real_path)
listfilepath.append(filepath)
#print(listfile)#符合条件的listfile
#print(listfilepath)#所有的路径
urllen=len(url)#输入文件夹路径长度
#print(urllen)#返回url长度
"""
listfile 是符合条件的文件,格式是绝对路径
listfilepath 是url条件的所有目录绝对路径
下一步目的是要将符合条件的文件,复制到指定位置的文件夹中。
2 把url之前的替换掉就行了。获得了保存路径
3 将文件copy到保存路径中去,
"""
for one in listfile:
i=save_dir+one[urllen:]#保存路径
one_path=i.split("\\")[:-1]#获取保存路径的目录
one_path="\\".join(one_path)#获取保存路径的目录
print(one_path)
isExist = os.path.exists(one_path)
if not isExist:
os.makedirs(one_path)
print("文件创建成功")
else :
print("文件已经存在")
shutil.copy(one,one_path)
代码demo3,经过大佬的问题讨论,对于文件和子文件夹的相对路径关系,发现只要将文件夹内的文件和文件夹全部遍历,获取符合后缀名的文件list,通过获取输入文件夹路径的长度,即找到长度、位置,然后将符合后缀的文件路径进行替换,拼接上保存路径。(子文件夹list其实都没有用)
于是完成list中绝对路径和保存文件路径的替换,就意味着可以完成保存路径的正确格式,然后创建保存路径,使用shutil库的copy函数copy即可。
缺陷:但没有考虑文件夹中是否会存在同名的子文件夹或文件。
总结:成熟的编程应该是忽略掉足够的细节,并完成抽象。