
python实现自动计算目录下md5
由于个人需求,准备实现一个py本实现遍历目录下所有文件并计算md5输出到列表中的需求。
1 基本思路
2 文件遍历
首先,我们需要先搞清楚python对文件的遍历操作,这里我们需要使用os库的listdir函数进行遍历,然后将文件输出到python的list对象中,代码如下:
def list_all_files(rootdir):
import os
_files = []
list = os.listdir(rootdir) #列出文件夹下所有的目录与文件
for i in range(0,len(list)):
path = os.path.join(rootdir,list[i])
if os.path.isdir(path):
_files.extend(list_all_files(path))
if os.path.isfile(path):
_files.append(path)
return _files
这样,就可以通过以下代码获取目录下的所有文件:
list_all_files(root);
其中,root参数是要遍历的目录根路径。现在,我们需要将遍历到的文件进行md5计算,看如下代码:
def get_file_md5(file_path):
if not os.path.isfile(file_path):
return
md5=hashlib.md5()
f=file(file_path,'rb')
if f:
while True:
b = f.read(8096)
if not b:
break
md5.update(b)
f.close()
return md5.hexdigest()
一样,我们可以使用如下代码调用:
get_file_md5(filepath)
3 计算MD5
现在,还有个问题,我们可以通过list_all_files遍历目录,也可以通过get_file_md5计算md5,但是怎么写入文件?在这里,我们使用python的open方法,使用方式如下:
#打开文件
file = open(list_file,"w")
#写入文件
file.write(data)
#关闭文件
file.close
4 参数解析
我们的脚本是需要参数才能运行的,因此,还需要解决参数解析的问题,python本身可以通过sys对象获取参数,但这里,我们选择使用argparse进行参数解析,相关代码如下:
parse = argparse.ArgumentParser()
parse.add_argument('path')
parse.add_argument('list_file')
args = parse.parse_args()
argparse的ArgumentParser方法有如下参数,含义如下:
参数 | 含义 |
---|---|
prog | 文件名,默认为sys.argv[0],用来在help信息中描述程序的名称。 |
usage | 描述程序用途的字符串 |
description | help信息前显示的信息 |
epilog | help信息之后显示的信息 |
parents | 由ArgumentParser对象组成的列表,它们的arguments选项会被包含到新ArgumentParser对象中。(类似于继承) |
formatter_class | help信息输出的格式,为了美观… |
prefix_chars | 参数前缀,默认为’-‘(最好不要修改) |
fromfile_prefix_chars | 前缀字符,放在文件名之前 |
conflict_handler | 解决冲突的策略,默认情况下冲突会发生错误,(最好不要修改) |
add_help | 是否增加-h/-help选项 (默认为True),一般help信息都是必须的。设为False时,help信息里面不再显示-h –help信息 |
argument_default | – (default: None)设置一个全局的选项的缺省值,一般每个选项单独设置,基本没用 |
接下来,我们需要了解下添加参数函数add_argument
,它的调用格式是:
ArgumentParser.add_argument(name or flags...[, action][, nargs][, const][, default][, type][, choices][, required][, help][, metavar][, dest])
调用参数含义是:
参数 | 含义 |
---|---|
argstring | 参数有两种,可选参数和位置参数。 |
action | 默认为store |
metaver | 帮助信息中显示的参数名称 |
nargs | 参数的数量 |
const | 保存一个常量 |
default | 默认值 |
type | 参数类型,默认为str |
choices | 设置参数值的范围,如果choices中的类型不是字符串,记得指定type |
required | 该选项是否必选,默认为True |
dest | 参数名 |
4.1 参数字符串
  参数格式有以下2种:
parser.add_argument('-f', '--foo')
parser.add_argument('bar')
这2种有不同的使用格式,第一种,则需要在使用以-或者–加参数名的形式 后面追加实参,另一种则直接在特定位置写参数即可,如:
# -f格式
./test.py -f XXX
或
./test.py --foo xxx
# 不带-格式
./test.py XXX
特定的参数会按指定的格式位置和形式,被自动解析。
4.2 行为方式
action参数决定了参数解析器解析到特定参数时的特定行为,分为如下类型:
action参数值 | 含义 |
---|---|
store_const | 值存放在const中 |
store_true和store_false | 值存为True或False |
append | 存为列表,可以有多个参数 |
append_const | 存为列表,会根据const关键参数进行添加 |
count | 统计参数出现的次数 |
help | 帮助信息 |
version | 版本 |
4.3 解析参数
最后,我们需要调用parse_args
函数进行解析,完整解析代码如下:
parse = argparse.ArgumentParser()
parse.add_argument('path')
parse.add_argument('list_file')
parse.add_argument('-m','--match',dest='match',default='^.*$',nargs='?')
args = parse.parse_args()
使用时,只需要将脚本文件按如下方式调用:
./md5print.py /www tmp.txt # path = '/www',list_file='tmp.txt'
5 最后
写到最后,我想大家已经知道如何实现这个脚本了,以下是脚本的完整代码:
#!/usr/bin/python
# coding=utf-8
import argparse,sys,hashlib,os
parse = argparse.ArgumentParser()
parse.add_argument('path')
parse.add_argument('list_file')
parse.add_argument('-m','--match',dest='match',default='^.*$',nargs='?')
args = parse.parse_args()
def list_all_files(rootdir):
import os
_files = []
list = os.listdir(rootdir) #列出文件夹下所有的目录与文件
for i in range(0,len(list)):
path = os.path.join(rootdir,list[i])
if os.path.isdir(path):
_files.extend(list_all_files(path))
if os.path.isfile(path):
_files.append(path)
return _files
def get_file_md5(file_path):
if not os.path.isfile(file_path):
return
md5=hashlib.md5()
f=file(file_path,'rb')
while True:
b = f.read(8096)
if not b:
break
md5.update(b)
f.close()
return md5.hexdigest()
def main():
list = list_all_files(args.path)
file = open(args.list_file,'w');
if file:
for filename in list:
if re.match(args.match,filename) != None:
md5 = get_file_md5(filename)
file.write('%s|%s\n' % (md5,os.path.abspath(filename)))
file.close()
if __name__ == '__main__':
main()