sys.argv[] 说白了就是一个从程序外部获取参数的桥梁 ,我们从外部取得的参数可以是多个 ,所以获得的是一个列表(list),也就是说sys.argv其实可以看作是一个列表 ,所以才能用[]提取其中的元素 。其第一个元素(sys.argv[0])是程序本身 ,随后才依次是外部给予的参数 。
argv[0] 表示本身代码文件路径
列表元素来自外部输入
外部输入从1开始
我们通过sys.argv[1]获取文件的名称。但是,这里有种异常情况需要考虑,如果用户直接运行我们的程序,没有传递任何命令行参数,那么,访问sys.argv[1]将会出现索引越界的错误。为了避免这个错误,我们可以在访问sys.argv之前先向sys.argv中添加一个空的字符串。添加空字符串以后,无论用户是否提供命令行参数,访问 sys.argv[1]都不会出错。如果用户传递了命令行参数,那么,通过sys.argv[1]访问,得到的是用户提供的命令行参数。
实现功能:
1.通过命令行输入目录
2.遍历该目录下的所有文件
3.通过md5校验判断文件是否相同
4.输入的文件判断该文件是否已经存在于字典中,字典的键是文件的md5校验码,字典的值是文件的名称。
# -*- coding: UTF-8 -*-
from __future__ import print_function
import os
import fnmatch
import sys
import hashlib
CHUNL_SIZE = 8192
def is_file_match(filename, patterns):
for pattern in patterns:
if fnmatch.fnmatch(filename, pattern):
return True
return False
def find_specific_files(root, patterns=['*'], exclude_dirs=[]):
for root, dirnames, filenames in os.walk(root):
for filename in filenames:
if is_file_match(filename, patterns):
yield os.path.join(root, filename)
for d in exclude_dirs:
if d in dirnames:
dirnames.remove(d)
def get_chunk(filename):
with open(filename) as f:
while True:
chunk = f.read(CHUNL_SIZE)
if not chunk:
break
else:
yield chunk
def get_file_checksum(filename):
h = hashlib.md5()
for chunk in get_chunk(filename):
h.update(chunk)
return h.hexdigest()
def main():
sys.argv.append("")
directory = sys.argv[1]
if not os.path.isdir(directory):
raise SystemExit("{0} is not a directory".format(directory))
record = {}
for item in find_specific_files(directory):
checksum = get_file_checksum(item)
if checksum in record:
print('find duplicate file: {0} vs {1}'.format(record[checksum], item))
else:
record[checksum] = item
if __name__ == '__main__':
main()