自己的需求是这样的:
有a和b两个目录,a目录下的文件(夹)要剪切到b目录下;我用下面这种形式来表达需求,不然说得比较乱。
需求如下:
a目录
1.文件:
1)是日志文件:
(1)文件大小<20m:
跳过
(2)日志文件>=20m:
复制名加上当天日期,然后剪切到b中(记录到日志文件中)
2)不是日志文件:
(1)不在b中:
直接剪切到b中(记录到日志文件中)
(2)在b中:
Name = Name + ’_’ ; 然后剪切到b中(记录到日志文件中)
2.文件夹:
1)文件夹不在b中:
直接剪切到b中(记录到日志文件中)
2)文件夹在b里面:
(1)文件夹内的文件(夹)也在b目录相同文件夹中:
命名方式同上:Name = Name + ’_’ ;然后剪切(记录到日志文件中)
(2)文件夹内的文件(夹)不在b目录相同文件夹中:
直接剪切所有文件(夹)(记录到日志文件中)
b目录
1.文件
2.文件夹
自己的实现步骤如下:版本一
#coding:utf-8
'''
一个剪切脚本
版本一:实现递归列出多有文件
'''
import os
import shutil
class Shear():
def __init__(self):
#源目录
self.src = "C:\\Users\\LZH\\Documents\\upupoo\\Docker\\config\\文件夹\\python练习\\shear\\a\\"
#目标目录
self.dest = "C:\\Users\\LZH\\Documents\\upupoo\\Docker\\config\\文件夹\\python练习\\shear\\b\\"
def start_shear(self,a_filepath):
for a_item in os.listdir(a_filepath): #遍历源目录下的所有文件
a_absolute_path = os.path.join(a_filepath,a_item) #新的目录为传入目录+传入目录里面的文件夹名称
is_file = os.path.isfile(a_absolute_path) #文件赋给 is_file
is_dir = os.path.isdir(a_absolute_path) #目录赋给 is_dir
if is_file:
if a_item =="数据传输日志.log":
pass
else:
print(a_item)
elif is_dir:
if a_item == "回盘文件":
pass
elif a_item == "已导入数据库":
pass
else:
print("目录为--%s--的有以下文件:"% a_item)
shear.start_shear(a_absolute_path)
if __name__ == "__main__":
shear = Shear()
shear.start_shear(shear.src)
版本二
#coding:utf-8
'''
一个文件移动脚本
版本一:实现递归列出多有文件
版本二:实现源目录和目的目录的文件移动
'''
import os
import shutil
class Shear():
def __init__(self):
#源目录
self.src = "C:\\Users\\LZH\\Documents\\upupoo\\Docker\\config\\文件夹\\python练习\\shear\\a\\"
#目标目录
self.dest = "C:\\Users\\LZH\\Documents\\upupoo\\Docker\\config\\文件夹\\python练习\\shear\\b\\"
def start_shear(self,a_filepath):
for a_item in os.listdir(a_filepath): #遍历源目录下的所有文件
a_absolute_path = os.path.join(a_filepath,a_item) #新的目录为传入目录+传入目录里面的文件夹名称
is_a_file = os.path.isfile(a_absolute_path) #文件赋给 is_file
is_a_dir = os.path.isdir(a_absolute_path) #目录赋给 is_dir
if is_a_file: #self.src 里是文件的话处理条件如下:
if a_item =="数据传输日志.log":
pass
elif a_item in os.listdir(self.dest): #如果该文件已经存在于目的目录中,则不操作
renamef = a_item.split('.') #将文件名及后缀分开
#print(rename)
os.rename(self.src+a_item, self.src+renamef[0]+"_."+renamef[1]) #若目的目录存在该目录,则修改名字,后加“_”
else:
shutil.move(self.src+a_item, self.dest) #shutil.move(full_path,destpath) 这里移动文件的源文件要完全路径,否则会报找不到文件的错
#os.rename(a_item,self.dest)
elif is_a_dir: #self.src 里是目录的话处理条件如下:
if a_item == "回盘文件备份" or a_item == "已导入数据库": #目录名为指定目录名时则不操作
pass
else:
#print(a_absolute_path)
os.chdir(a_absolute_path) #更改目录为src里的每个目录
if a_item not in os.listdir(self.dest): #判断src里面的每一个目录是否在dest里,不在则执行
os.makedirs(self.dest+a_item) #在dest中创建和src中一样的目录
else:
mk = self.dest+a_item
for ch_item in os.listdir(a_absolute_path): #存在则遍历src中每个目录里的所有文件
if ch_item not in os.listdir(mk): #文件若不在上一次执行创建的目录中,则移动该文件到新创建的目录中
if ch_item == "已导入数据库" or ch_item =="回盘文件": #文件夹中存在该名称目录则跳过 ;否 则移动
pass
else:
shutil.move(ch_item, mk)
else:
#print("文件已存在,无法移动文件: %s" % ch_item) #若新创建的目录中已经包含该文件,则提示无法移动
if os.path.isdir(self.src+a_item+"\\"+ch_item): #当目的目录内文件夹有该文件夹时
os.rename(self.src + a_item + "\\" + ch_item,self.src + a_item + "\\" + ch_item + "_")#则修改文件名+“_”,在第二次执行中移动文件,若还存在,则重复前面步骤,直至移动到目的目录
else: #目录下为文件时则操作如下
renamed = ch_item.split('.')
os.rename(self.src+a_item+"\\"+ch_item, self.src+a_item+"\\"+renamed[0]+"_."+renamed[1])
if __name__ == "__main__":
shear = Shear()
shear.start_shear(shear.src)
版本三:
#coding:utf-8
'''
一个文件移动脚本
版本一:实现递归列出多有文件
版本二:实现源目录和目的目录的文件移动
版本三:实现日志记录及日志备份
'''
import os
import shutil
from datetime import datetime
class Shear():
def __init__(self):
#源目录
self.src = "C:\\Users\\LZH\\Documents\\upupoo\\Docker\\config\\文件夹\\python练习\\shear\\a\\"
#目标目录
self.dest = "C:\\Users\\LZH\\Documents\\upupoo\\Docker\\config\\文件夹\\python练习\\shear\\b\\"
'''文件(夹)移动部分'''
def start_shear(self,a_filepath):
for a_item in os.listdir(a_filepath): #遍历源目录下的所有文件
a_absolute_path = os.path.join(a_filepath,a_item) #新的目录为传入目录+传入目录里面的文件夹名称
is_a_file = os.path.isfile(a_absolute_path) #文件赋给 is_file
is_a_dir = os.path.isdir(a_absolute_path) #目录赋给 is_dir
if is_a_file: #self.src 里是文件的话处理条件如下:
if a_item == "数据传输日志.log":
shear.back_log(self.src+a_item) #进入日志文件备份判断程序
elif a_item in os.listdir(self.dest): #如果该文件已经存在于目的目录中,则不操作
renamef = a_item.split('.') #将文件名及后缀分开
#print(rename)
os.rename(self.src+a_item, self.src+renamef[0]+"_."+renamef[1]) #若目的目录存在该目录,则修改名字,后加“_”
else:
asize = round(os.path.getsize(self.src+a_item)/1024, 2) #os.path.getsize获取文件大小,round()函数取值范围:小数点后两位
shutil.move(self.src+a_item, self.dest) #shutil.move(full_path,destpath) 这里移动文件的源文件要完全路径,否则会报找不到文件的错
shear.log(a_item, self.dest, asize, '源目录中')
#os.rename(a_item,self.dest)
elif is_a_dir: #self.src 里是目录的话处理条件如下:
if a_item == "回盘文件备份" or a_item == "已导入数据库": #目录名为指定目录名时则不操作
pass
else:
#print(a_absolute_path)
os.chdir(a_absolute_path) #更改目录为src里的每个目录
if a_item not in os.listdir(self.dest): #判断src里面的每一个目录是否在dest里,不在则执行
os.makedirs(self.dest+a_item) #在dest中创建和src中一样的目录
else:
mk = self.dest+a_item
for ch_item in os.listdir(a_absolute_path): #存在则遍历src中每个目录里的所有文件
if ch_item not in os.listdir(mk): #文件若不在上一次执行创建的目录中,则移动该文件到新创建的目录中
if ch_item == "已导入数据库" or ch_item =="回盘文件": #文件夹中存在该名称目录则跳过 ;否 则移动
pass
else:
asize = round(os.path.getsize(ch_item)/1024,2) #os.path.getsize获取文件大小,round()函数取值范围:小数点后两位
shutil.move(ch_item, mk)
shear.log(ch_item, mk, asize, a_item)
else:
#print("文件已存在,无法移动文件: %s" % ch_item) #若新创建的目录中已经包含该文件,则提示无法移动
if os.path.isdir(self.src+a_item+"\\"+ch_item): #当目的目录内文件夹有该文件夹时
os.rename(self.src + a_item + "\\" + ch_item,self.src + a_item + "\\" + ch_item + "_")#则修改文件名+“_”,在第二次执行中移动文件,若还存在,则重复前面步骤,直至移动到目的目录
else: #目录下为文件时则操作如下
renamed = ch_item.split('.')
os.rename(self.src+a_item+"\\"+ch_item, self.src+a_item+"\\"+renamed[0]+"_."+renamed[1])
'''记录日志部分'''
def log(self, data, dest, size, bankname): #文件名;目的目录;大小;银行名称
record = open(self.src+"数据传输日志.log", 'a')
record.write("%s-*********-" % datetime.now().strftime('%Y-%m-%d : %H:%M')+"来源:%s" % bankname+"\t文件:%s" % data +"\t大小:%sk" % size +"\t移动到:%s" % dest +"\n")
'''日志文件备份'''
def back_log(self,log_file):
log_size = round(os.path.getsize(log_file)/(1024*1024),1)
if log_size >= 20: #若日志文件超过20m,则备份文件
shutil.copyfile(self.src+"数据传输日志.log",self.dest+"数据传输日志%s.log" % datetime.now().strftime('%Y-%m-%d') )
else:
pass
if __name__ == "__main__":
shear = Shear()
shear.start_shear(shear.src)
到此为止基本功能都实现了,就是感觉写得挺麻烦的。说说存在的问题:
1.假设a目录中既有文件又有文件夹,程序第一次执行只操作了文件,第二次操作才轮到文件夹。这个问题怎么解决好?
2.该程序并没有递归判断b目录中是否也存在相同文件,而是第二层目录后的目录直接剪切到了b目录对应位置,若是存在我用了重命名这个方式来解决,但若是后续有这个需求,程序还需要完善
3.shutil.move()在文件没其他程序占用的时候照样会被剪走,这个我感觉很不好的地方,尝试过用os.rename()。也是没有报错,这个问题有没有更好的解决方式?