一、问题引出
有时候比较懒,各种文件都堆积在桌面或者某个文件夹,想整理的时候发现已是满屏,不知如何下手!!!
笔者最近又遇见此问题,哎,要是能写个自动分类的脚本就好了!思虑半天,草草得出一点思路!
为了方便分享,自动构建了一个文件夹,随便生成了几个文件,如下图:
image.png
假设该文件夹就是那需要自动整理的乱七八糟的文件夹。
二、问题分析
笔者希望的是,通过一段代码,自动选择出文件名称中,频率最高的公共词组,将这些词组作为类别,接着基于各类别创建文件夹,最后把对应的文件移动到对应的类别中去,如前四个文件,希望创建一个名称为年工作总结的文件夹,然后把前四个文件都移动到此文件夹下。
整理一下总体思路:
1、计算出存在的公共词组并将词组按照出现次数降序排列
- 公共词组需要文件名称两两匹配
- 词组中要去除特殊词组,如数字、或者一些形式词组,如基于、关于、的等
2、将词组作为类别创建文件夹
3、遍历文件,将文件名与类别匹配,优先将匹配上的文件移动到对应上的类别中频率最高的文件夹中
三、代码实现
为了马上看到效果,以下过程实现比较简单粗暴,不要介意(⊙o⊙)…
1、公共词组获取函数
from collections import Counter
import os,shutil
import re
def get_common_sequence(word1,word2,filter='\d|关于|基于|于的|方案|分析+'):
'''
获取两文件名中所有公共词组
:param word1:
:param word2:
:param filter: 需要过滤的词组
:return:
'''
condidates = set()
last_condidate = ''
word1 = word1+"1"
word2 = word2+"2"
for i in range(len(word1)):
for j in range(len(word2)):
if word1[i] == word2[j]:
c_word1 = word1[i:]
c_word2 = word2[j:]
condidate = c_word1[0]
for k in range(1,min(len(c_word1),len(c_word2))):
if c_word1[k] == c_word2[k]:
condidate += c_word1[k]
else:
if len(condidate)>1:
if condidate not in last_condidate and not re.match(filter,condidate):
condidates.add(condidate)
last_condidate = condidate
break
condidate = ''
return condidates
2、分类函数
def classify(path):
classifications = []
files = os.listdir(path)
for file in files:
for file2 in files:
if file != file2:
classification = get_common_sequence(file.split('.')[0],file2.split('.')[0])
classifications.extend(classification)
classifications_counter = Counter(classifications)
for file in files:
for dir in classifications_counter.keys():
if dir in file:
if os.path.exists(path+dir):
shutil.move(path+file,path+dir)
break
else:
os.mkdir(path + dir)
shutil.move(path + file, path + dir)
break
3、执行
classify('需要分类的文件夹路径')
效果如下
以上就是整个过程,将其保存为脚本,每次运行传入需要分类的路径即可。
网友评论