在上古时代,由于阅读设备垃圾,所以很多txt文件都被分割为以章为单位,一个完整的文件往往要占据一个文件夹,强迫症根本忍受不了。所以希望通过python对txt文件进行合并。
文章目录
1.汉字转数字
合并txt文件需要遵循一个前后顺序,如果文件名中包含数字是最好的,尤其是位数相同的数字,这时文件名读取函数os.listdir
会自动按照数字顺序读取。然而,若文件名是通过汉字进行排序的,那就有些不妙了。
对于型如一千二百五十五
这样的汉字,千、百、十的作用显然强于一、二、五,因为它们决定了位数。如果说类似一、二、五这样的数字可以直接通过字典转化为1,2,5
,那么千、百十则需要对其前面的数字乘以1000,100以及10。
由于我要处理的文件一般不超过十万个,所以最大位数从万开始。
unitDict={ "零":0,"":1,"一":1,"二":2,"两":2,"三":3,"四":4,"五":5,"六":6,"七":7,"八":8,"九":9}
decadeDict={ "万":10000,"千":1000,"百":100,"十":10}
#十万以内的汉字转数字
def zh2num(name):
val = 0
for sym in decadeDict.copy():
if sym in name:
pre,name = name.split(sym) #字符串分割
val += decadeDict[sym]*unitDict[pre]
if name != "":
val += unitDict[name]
return val
2. 字符排序
接下来,以汉字转数字为核心算法,来写一个字符排序的函数。由于我们不确定文件名中的序号到底是汉字还是数字,所以需要把二者都考虑进来,然后据此建立字典,通过字典的键对值进行排序,最后输出排好序的文件名列表。
# 如果字符串中存在中文数字,对其进行排序
def sortStr(files,flag=0):
nums = "0123456789"
zhs = list(unitDict.keys())+list(decadeDict.keys())
sortDict = { }
end = len(files)
for f in files:
nStr = "".join([c for c in list(f[:flag] if flag>0 else f) if c in nums])
zStr = "".join([c for c in list(f[:flag] if flag>0 else f) if c in zhs])
if nStr != "":
sortDict[int(nStr)] = f
elif zStr !="":
sortDict[zh2num(zStr)] = f
else:
end += 1
sortDict[end]=f
return [sortDict[n] for n in np.sort(list(sortDict))]
需要注意的是,这个函数的适用条件非常有限,如果想应对更多的情况,还是需要继续改进的。
3. 文本文档合并
最后写出主程序,输入文件路径后,通过os.listdir
读取文件夹中的文件名,需要注意,打开文件的时候可能会遇到一些诡异的字符,所以我们选择忽略错误errors="ignore
。
def emerge(path,flag=0):
files = sortStr(os.listdir(path),flag)
newTxt = open(path+".txt","w",encoding="GBK")
path += "\\"
for f in files:
try:
txt = open(path+f,"r",encoding='GBK',errors="ignore")
newTxt.write(f.split(".txt")[0]+"\n")
strs = txt.read()
newTxt.write(strs+"\n")
except Exception as e:
print(path+f)
print(e)
newTxt.close()