前几天接到一个任务,从gerrit上通过ssh命令获取一些commit相关的数据到文本文档中,随后将这些数据存入Excel中。数据格式如下图所示

观察上图可知,存在文本文档中的数据符合一定的格式,通过python读取、正则表达式处理并写入Excel文档将大大减少人工处理的工作量。

  1. 从gerrit获取原始信息,存入文本文档:

  $ssh –p 29418 <your-account>@192.168.1.16 gerrit query status:merged since:<date/7/days/ago> 2>&1 | tee merged_patch_this_week.txt

  2. 从txt文档中读取数据。

  Python的标准库中,文件对象提供了三个“读”方法: .read()、.readline() 和 .readlines()。每种方法可以接受一个变量以限制每次读取的数据量,但它们通常不使用变量。 .read() 每次读取整个文件,它通常用于将文件内容放到一个字符串变量中。然而 .read() 生成文件内容最直接的字符串表示,但对于连续的面向行的处理,它却是不必要的,并且如果文件大于可用内存,则不可能实现这种处理。

  readline() 和 readlines()之间的差异是后者一次读取整个文件,象 .read()一样。.readlines()自动将文件内容分析成一个行的列表,该列表可以由 Python 的 for... in ... 结构进行处理。另一方面,.readline()每次只读取一行,通常比 .readlines()慢得多。仅当没有足够内存可以一次读取整个文件时,才应该使用.readline()。

patch_file_name="merged_patch_this_week.txt"
patch_file=open(patch_file_name,'r') #打开文档,逐行读取数据
for line in open(patch_file_name):
line=patch_file.readline()
print line

  3. 写入到Excel文档中

    python处理Excel的函数库中,xlrd、xlwt、xlutils比较常用,网上关于它们的资料也有很多。但由于它们都不支持Excel 2007以后的版本(.xlsx),所以只能忍痛放弃。

经过一番搜索,找到了openpyxl这个函数库,它不仅支持Excel 2007,并且一直有人维护(当前最新版本为2.2.1,2015年3月31日发布)。官方的描述为:

A Python library to read/write Excel 2007 xlsx/xlsm files,它的文档清晰易读,相关网站:http://openpyxl.readthedocs.org/en/latest/index.html

  openpyxl 下载地址:https://bitbucket.org/openpyxl/openpyxl/get/2.2.1.tar.bz2

  它依赖于jdcal 模块,下载地址: https://pypi.python.org/packages/source/j/jdcal/jdcal-1.0.tar.gz

  安装方法(windows 7):首先安装jdcal模块--解压缩到某目录,cd到该目录,运行"python setup.py install"。 然后安装openpyxl,方法相同。

  写入步骤如下:

  1. 打开工作簿:

wb=load_workbook('Android_Patch_Review-Y2015.xlsx')

  2. 获得工作表

sheetnames = wb.get_sheet_names()
ws = wb.get_sheet_by_name(sheetnames[2])

  3. 将txt文档中的数据写入并设置单元格格式

patch_file_name="merged_patch_this_week.txt"
patch_file=open(patch_file_name,'r') #打开文档,逐行读取数据
ft=Font(name='Neo Sans Intel',size=11)
for line in open(patch_file_name):
line=patch_file.readline()
ws.cell(row=1,column=6).value=re.sub('project:','',line)#匹配project行,若匹配成功,则将字符串“project:”删除,剩余部分写入Excel第1行第6列
ws.cell(row=rows+1,column=1).font=ft

  4. 保存工作簿

wb.save('Android_Patch_Review-Y2015.xlsx')

完整代码如下:

from openpyxl.workbook import Workbook
from openpyxl.reader.excel import load_workbook
from openpyxl.styles import PatternFill, Border, Side, Alignment, Protection, Font
import re
#from openpyxl.writer.excel import ExcelWriter
#import xlrd ft=Font(name='Neo Sans Intel',size=11) #define font style
bd=Border(left=Side(border_style='thin',color=''),\
right=Side(border_style='thin',color=''),\
top=Side(border_style='thin',color=''),\
bottom=Side(border_style='thin',color='')) #define border style
alg_cc=Alignment(horizontal='center',\
vertical='center',\
text_rotation=0,\
wrap_text=True,\
shrink_to_fit=True,\
indent=0) #define alignment styles
alg_cb=Alignment(horizontal='center',\
vertical='bottom',\
text_rotation=0,\
wrap_text=True,\
shrink_to_fit=True,\
indent=0)
alg_lc=Alignment(horizontal='left',\
vertical='center',\
text_rotation=0,\
wrap_text=True,\
shrink_to_fit=True,\
indent=0) patch_file_name="merged_patch_this_week.txt"
patch_file=open(patch_file_name,'r') #get data patch text wb=load_workbook('Android_Patch_Review-Y2015.xlsx') #open excel to write
sheetnames = wb.get_sheet_names()
ws = wb.get_sheet_by_name(sheetnames[2]) #get sheet
rows=len(ws.rows) assert ws.cell(row=rows,column=1).value!=None, 'New Document or empty row at the end of the document? Please input at least one row!'
print "The original Excel document has %d rows totally." %(rows)
end_tag='type: stats' for line in open(patch_file_name):
line=patch_file.readline()
if re.match(end_tag,line) is not None: #end string
break
if len(line)==1: #go to next patch
rows=rows+1
continue
line = line.strip()
# print line
ws.cell(row=rows+1,column=1).value=ws.cell(row=rows,column=1).value+1 #Write No.
ws.cell(row=rows+1,column=1).font=ft
ws.cell(row=rows+1,column=1).border=bd
ws.cell(row=rows+1,column=1).alignment=alg_cb
ws.cell(row=rows+1,column=5).border=bd
ws.cell(row=rows+1,column=9).border=bd if re.match('change',line) is not None:
ws.cell(row=rows+1,column=2).value=re.sub('change','',line) #Write Gerrit ID
ws.cell(row=rows+1,column=2).font=ft
ws.cell(row=rows+1,column=2).border=bd
ws.cell(row=rows+1,column=2).alignment=alg_cb if re.match('url:',line) is not None:
ws.cell(row=rows+1,column=3).value=re.sub('url:','',line) #Write Gerrit url
ws.cell(row=rows+1,column=3).font=ft
ws.cell(row=rows+1,column=3).border=bd
ws.cell(row=rows+1,column=3).alignment=alg_cb if re.match('project:',line) is not None:
ws.cell(row=rows+1,column=6).value=re.sub('project:','',line) #Write project
ws.cell(row=rows+1,column=6).font=ft
ws.cell(row=rows+1,column=6).border=bd
ws.cell(row=rows+1,column=6).alignment=alg_lc if re.match('branch:',line) is not None:
ws.cell(row=rows+1,column=7).value=re.sub('branch:','',line) #Write branch
ws.cell(row=rows+1,column=7).font=ft
ws.cell(row=rows+1,column=7).border=bd
ws.cell(row=rows+1,column=7).alignment=alg_cc if re.match('lastUpdated:',line) is not None:
ws.cell(row=rows+1,column=8).value=re.sub('lastUpdated:|CST','',line) #Write update time
ws.cell(row=rows+1,column=8).font=ft
ws.cell(row=rows+1,column=8).border=bd
ws.cell(row=rows+1,column=8).alignment=alg_cc if re.match('commitMessage:',line) is not None:
description_str=re.sub('commitMessage:','',line)
if re.match('Product:|BugID:|Description:|Unit Test:|Change-Id:',line) is not None:
description_str=description_str+'\n'+line #
if re.match('Signed-off-by:',line) is not None:
description_str=description_str+'\n'+line
ws.cell(row=rows+1,column=4).value=description_str #Write patch description
ws.cell(row=rows+1,column=4).font=ft
ws.cell(row=rows+1,column=4).border=bd
ws.cell(row=rows+1,column=4).alignment=alg_lc
wb.save('Android_Patch_Review-Y2015.xlsx')
print 'Android_Patch_Review-Y2015.xlsx saved!\nPatch Collection Done!'
#patch_file.close()

目前为止,基本功能已经实现,但是还有两个问题没有搞明白:

第一个是完整代码中的最后一句注释行,我搜到的几篇介绍openpyxl的博客中,打开文件后都没有close,所以我在代码中也没有close。理论上感觉还是需要的。等对文件对象的理解更加深入一些时会继续考虑这个问题。

第二是运行该脚本时有一个warning," UserWarning: Discarded range with reserved name,warnings.warn("Discarded range with reserved name")“,目前还在搜索原因,如有明白的,也请不吝告知。

  (参考:http://blog.csdn.net/werm520/article/details/6898473

用python从符合一定格式的txt文档中逐行读取数据并按一定规则写入excel(openpyxl支持Excel 2007 .xlsx格式)的更多相关文章

  1. 使用2种python脚本工具将2个txt文档中的文字进行比较,并计算出Corr, WER正确率,准确率

    一.准备: linux服务器,src2mlf.py   rec2mlf.py   HResults文件,1份源文件和1份需要对比的文件.文件放置于本人云盘 二.使用方法: 1. 对比工具 HResul ...

  2. 一个简易的Python爬虫,将爬取到的数据写入txt文档中

    代码如下: import requests import re import os #url url = "http://wiki.akbfun48.com/index.php?title= ...

  3. 用matlab查找txt文档中的关键字,并把关键字后面的数据存到起来用matlab处理

    用matlab查找txt文档中的关键字,并把关键字后面的数据存到起来用matlab处理 我测了一组数据存到txt文件中,是个WIFI信号强度文档,里面有我们需要得到的数据,有没用的数据,想用matla ...

  4. 提取一个txt 文档中含指定字符串的所有行

    将一个txt 文档中含指定字符串内容的所有行提取出来并保存至新的txt文档中 例如,要提取 1.txt 中所有包含”aaa” 的行的内容 只需在此文件夹中新建一个bat文件,输入以下代码,双击运行,便 ...

  5. 网络抓取功能实现 将获取的结果进行过滤并写入到TXT文档中

    下面是自己编写的 网络抓取功能实现 将获取的结果进行过滤并写入到TXT文档中 (以防忘记) 原创哟 import java.io.BufferedReader;import java.io.Buffe ...

  6. 输出5个大写英文字母的组合,并写入到txt文档中,随机数法。

    1.问题起源:最近想申请几个英文商标,研究了一下,英文字母在4到7个之间最好,5个字母尤佳,所以先来输出5个字母的组合,可是想像力有限,于是想用排列组合把所有5个可能的字母组合都输出,再从中挑选几个感 ...

  7. C语言,产生一组数字,并将其写入txt文档中

    #include<stdio.h> /*产生一组连续的数字,并将其写到txt文档中*/ /*说明:本程序在在win10 系统64位下用Dev-C++ 5.11版本编译器编译的*/int m ...

  8. 将mat文件中的数据按要求保存到txt文档中(批处理)

    之前有个老朋友,让帮忙将一个mat中的数据重新保存到txt中,由于数据比较多需要用到批处理,之前弄过很多次,但每次一到要用的时候总是忘记怎么写了,现在记录一下,免得后面老是需要上网搜.这里先说一个比较 ...

  9. java使用正则从爬虫爬的txt文档中提取QQ邮箱

    我的需求是从一堆文档中提取出qq邮箱,写了这篇帖子,希望能帮助和我有一样需求的人,谢谢!...... import java.io.BufferedReader; import java.io.Fil ...

随机推荐

  1. 使用scrapy-crawlSpider 爬取tencent 招聘

    Tencent 招聘信息网站 创建项目 scrapy startproject Tencent 创建爬虫 scrapy genspider -t crawl tencent 1. 起始url  sta ...

  2. memcached的部署

    window下memcached注册服务 cmd:在学习Memcached时,为了模拟分布存储,常常需要建多个Memcached服务,如何建呢,只能使用命令行了 以管理员身份运行cmd,输入如下命令 ...

  3. 「THUWC 2017」在美妙的数学王国中畅游

    这个题目很明显在暗示你要用泰勒展开. 直接套上去泰勒展开的式子,精度的话保留12项左右即可. 分别维护每一项的和,可能比较难写吧. 然后强行套一个LCT就没了.

  4. Two Melodies CodeForces - 813D (DP,技巧)

    https://codeforces.com/problemset/problem/813/D dp[i][j] = 一条链以i结尾, 另一条链以j结尾的最大值 关键要保证转移时两条链不能相交 #in ...

  5. csrf漏洞

    漏洞原理:csrf全名为跨站请求伪造,是一种对网站的恶意利用,虽然听起来和xss很像,但是它们俩还是有很大的区别的.csrf是通过伪造来自受信任用户的请求来利用受信任的网站. 比如: 一个有csrf漏 ...

  6. 【Java】【5】List随机取值

    //shuffle 打乱顺序 Collections.shuffle(list); //随机抽取1个值 System.out.println(list.get(0)); //随机抽取N个值 Syste ...

  7. 2017-3-29/HTTP协议1

    1. 讲讲你对http的理解. HTTP协议(HyperText Transfer Protocol,超文本传输协议)是用于从WWW服务器传输超文本到本地浏览器的传输协议,是一个客户端和服务器端请求和 ...

  8. Hadoop 2.7.3 完全分布式维护-部署篇

    测试环境如下  IP       host JDK linux hadop role 172.16.101.55 sht-sgmhadoopnn-01 1.8.0_111 CentOS release ...

  9. Oracle Log Block Size

    Although the size of redo entries is measured in bytes, LGWR writes the redo to the log files on dis ...

  10. 【转】Entity Framework Extended Library (EF扩展类库,支持批量更新、删除、合并多个查询等)

    E文好的可以直接看https://github.com/loresoft/EntityFramework.Extended 也可以在nuget上直接安装这个包,它的说明有点过时了,最新版本已经改用对I ...