前几天接到一个任务,从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. 在线linux 平台

    1.http://www.shiyanlou.com/[实验楼] 2.http://bellard.org/jslinux/[大牛平台]

  2. java多线程wait()方法必须放在while循环里面的原因探析

    1.写一个包子生产消费案例:一次生产或消费一个包子,有包子就消费,没有就生产.(部分代码参考传智播客刘意2015Java基础视频讲义) 1.1 写一个Baozi.class,包含main()方法,用来 ...

  3. QPS 机器计算公式

    QPS = req/sec = 请求数/秒 QPS = 总请求数 / ( 进程总数 * 请求时间 )QPS: 单个进程每秒请求服务器的成功次数 原理:每天80%的访问集中在20%的时间里,这20%时间 ...

  4. 使用org.apache.poi导出Excel表格

    public HSSFWorkbook MakeExcel(List<TransactionLogVO> logList) { // SimpleDateFormat sdf = new ...

  5. MySQL 分支和循环结构

    1.if else分支 mysql:用elseif               Oracle:用elsif 可以用select直接查看获取的值或者一个变量. create procedure pd_t ...

  6. 数据结构与算法之PHP实现二叉树的遍历

    一.二叉树的遍历 以某种特定顺序访问树中所有的节点称为树的遍历,遍历二叉树可分深度优先遍历和广度优先遍历. 深度优先遍历:对每一个可能的分支路径深入到不能再深入为止,而且每个节点只能访问一次.可以细分 ...

  7. PostgreSQL主备流复制机制

    原文出处 http://mysql.taobao.org/monthly/2015/10/04/ PostgreSQL在9.0之后引入了主备流复制机制,通过流复制,备库不断的从主库同步相应的数据,并在 ...

  8. Oracle11g版本中未归档隐藏参数

    In this post, I will give a list of all undocumented parameters in Oracle 11g. Here is a query to se ...

  9. nginx 拒绝本地ip访问

    server { listen default_server; server_name _; server_name localhost; ; }

  10. Cppcheck - A tool for static C/C++ code analysis

    cppcheck是一个个检测源码的工具,对编译工具的一个补充,mark Cppcheck - A tool for static C/C++ code analysis Syntax: cppchec ...