写出第一个python脚本解决问题后的一点感悟:千万别埋头学太久理论知识,而是要亲自动手,不然你永远也无法走出新手村。
废话不多说,我遇到的问题是,我有一个如下所示的test.txt文本文件:
>124sabhj
ahqhboatxuyqwd
nlksa
65dwo;q5
qdwli
>dkjadjqw
efwhj
jwqldikjqlkwdpoq
我想要去掉该文件的一些换行符,改为下面的文本形式:
>124sabhj
ahqhboatxuyqwdnlksa65dwo;q5qdwli
>dkjadjqw
efwhjjwqldikjqlkwdpoq
作为新手,肯定要参考别人写的脚本,当然参考不是抄,一定要一步步搞清楚含义,我首先参考了下面的帖子:
参考脚本链接
其代码如下,我每行附上注释,即我的理解:
import os #python中import语句用来导入其他模块,这里指导入os模块,因为倒数第一行和倒数第三行用到了os模块
filePath = "test.txt" #将需要编辑的纯文本文件test.txt的路径和名称赋给变量filePath
fr = open(filePath, "rb") #open()函数打开test.txt文件,rb指用二进制只读方式打开,并将读取的内容赋给变量fr,open()函数返回一个文件对象,可以理解为我们打开文档的点击动作
fw = open(filePath + ".bak", "wb+") #open()函数创建文件test.txt.bak,并以二进制写入方式打开
lineList = fr.readlines() #读取文件所有行,并将内容以列表的形式赋给变量lineList,可以这样理解,我们通过open()函数双击点开了test.txt文件,而readlines是对这个打开的文件进行阅读,并存储到变量
for line in lineList: #for循环,lineList是一个列表,line是这个列表中的全部元素,即每一行内容
str = line.decode("UTF-8", "ignore") #对内容进行解码,由于是二进制打开的,因此,要解码才是文本内容
if str.find("0") != -1: #文本中搜到0时,进行下面的操作
str = str.replace("0", "a") #用a代替0
line = str.encode() #将字符串编码为二进制格式
fw.write(line) #以二进制格式写入文件test.txt.bak
else: #否则,即没搜到0时
fw.write(line) #将二进制格式的line直接写入文件test.txt.bak
fr.close() #关闭文件test.txt
fw.close() #关闭文件test.txt.bak
os.remove(fr.name) #删除test.txt文件
newName = fw.name.replace(".bak","") #将test.txt.bak文件名称去掉.bak,即名称为test.txt,并将该名称赋给变量newName
os.rename(fw.name, newName) #将test.txt.bak文件改名为变量newName,即test.txt
万事开头难,但如果站在别人的肩膀上就不一样了。
参考别人的脚本,我们理一下自己的思路:
首先,打开test.txt文件,同时创建新的文件test.txt.bak,读取test.txt的每一行内容。
接着,进入条件语句:
当行内容中有“>”时,直接写入test.txt.bak;
当行内容中无“>”,但下一行中有“>”时,直接写入test.txt.bak文件中;
其他情况,删除末尾的换行符“\n”,然后将行内容写入test.txt.bak文件中。
最后,关闭test.txt文件和test.txt.bak文件,删除test.txt文件,并将test.txt.bak文件改名为test.txt文件,至此,脚本结束。
可以看出,整体的框架参考的脚本已经给出了,我们基本只要设计一下条件语句就行了,但是,我们还是可以手动敲一遍,更加透彻地理解python脚本的运作。
第一部分语句,看了很多人写的脚本,一般有三个内容:
#!/usr/bin/python,指定调用的python解释器,可以理解为软件没有快捷方式时,直接去软件的文件夹里打开它,对linux用户适用;
#coding=utf-8或者# -- coding: UTF-8 --,两种写法都可以,作用是声明python代码的文本格式是utf-8编码。该声明针对python2.x的版本,而Python3.x默认使用utf-8编码格式,不需要在前面声明;
import语句,导入其他模块,这里需要导入os模块。
我的语句是在windows系统上,使用python3写的,于是,我们第一句语句为:
import os
第二部分语句,打开需要编辑的文件,并将所有行读入列表,这一部分需要掌握两个函数,即open()函数和readlines()函数,直接搜索它们的用法就会发现,使用open()函数没必要选择二进制读写,于是,我们的语句写为:
import os
filepath = 'C:/Users/dell/Desktop/test.txt' #将处理的文件名称和路径赋给变量filepath
fr = open(filepath, 'r') #以只读的方式打开文件
fw = open(filepath + '.bak', 'w') #创建临时文件test.txt.bak,并写入内容
linelist = fr.readlines() #将文件的每一行输入列表linelist
第三部分语句,需要掌握两个知识,循环语句和条件控制,因为我们要对比当前行和下一行,所以,循环语句需要修改一下,代替原脚本提取每个元素,我们提取每个元素的位置,语句为:
import os
filepath = 'C:/Users/dell/Desktop/test.txt' #将处理的文件名称和路径赋给变量filepath
fr = open(filepath, 'r') #以只读的方式打开文件
fw = open(filepath + '.bak', 'w') #创建临时文件test.txt.bak,并写入内容
linelist = fr.readlines() #将文件的每一行输入列表linelist
for i in range(len(linelist) - 1): #len()函数用于统计字符串的长度;range()函数创建一个整数列表,一般用在for循环中,总的来说,这个for语句是提取了列表第一个元素到倒数第二个元素的位置信息(range函数是左闭右开区间)
下面,编写条件语句:
import os
filepath = 'C:/Users/dell/Desktop/test.txt' #将处理的文件名称和路径赋给变量filepath
fr = open(filepath, 'r') #以只读的方式打开文件
fw = open(filepath + '.bak', 'w') #创建临时文件test.txt.bak,并写入内容
linelist = fr.readlines() #将文件的每一行输入列表linelist
for i in range(len(linelist) - 1):
if linelist[i].find('>') != -1:
fw.writelines(linelist[i])
elif linelist[i].find('>') == -1 and linelist[i + 1].find('>') != -1:
fw.writelines(linelist[i])
else:
linelist[i] = linelist[i].replace('\n', '')
fw.writelines(linelist[i])
fw.writelines(linelist[len(linelist) - 1])
linelist[i]指从第一个到倒数第二个元素;
find()函数用于检测字符串中是否包含子字符串;linelist[i].find(‘>’)指每一行内容中是否包括符号‘>’,如果没有时,就返回-1;
因为for循环没有提取到最后一行内容,所以用fw.writelines(linelist[len(linelist) - 1])这行语句
将最后一行内容直接写入test.txt.bak文件。
最后一部分,关闭文件,并删除原文件,保存创建的文件,全部脚本内容为:
import os
filepath = 'C:/Users/dell/Desktop/test.txt' #将处理的文件名称和路径赋给变量filepath
fr = open(filepath, 'r') #以只读的方式打开文件
fw = open(filepath + '.bak', 'w') #创建临时文件test.txt.bak,并写入内容
linelist = fr.readlines() #将文件的每一行输入列表linelist
for i in range(len(linelist) - 1):
if linelist[i].find('>') != -1:
fw.writelines(linelist[i])
elif linelist[i].find('>') == -1 and linelist[i + 1].find('>') != -1:
fw.writelines(linelist[i])
else:
linelist[i] = linelist[i].replace('\n', '')
fw.writelines(linelist[i])
fw.writelines(linelist[len(linelist) - 1])
fr.close()
fw.close()
os.remove(fr.name)
newName = fw.name.replace('.bak', '')
os.rename(fw.name, newName)
在写第一个python脚本的过程中远没有这一篇文章写的这么简单,期间,遇到了很多的问题,有时因为一个字母的丢失而导致整个脚本无法运行。虽然过程中十分艰难,但当看到自己一字一字敲出的脚本运行起来,解决了自己的问题时,啥都值了。我对python还没有系统学习,文中如有不对的地方,劳烦指出。谨以此文纪念我这第一个脚本,简单却不易。