您应该能够跟踪代码中发生的事情.
import zipfile
import os
search_string = 'ERROR '
exclude_file = 'Test.txt' # include filename with extension
outputfile = 'C:\\Python testing\\my file.txt'
rootzipfile = 'C:\\Python testing\\Logs-node1.zip'
PATH_SEPARATOR = os.sep
def find_string_in_nested_zip(filepath, zf=None, extra_path_info=''):
if not(is_zip_or_nested_zip(filepath, zf)) and not(is_dir(filepath)) and \
not(filepath.endswith(exclude_file)) and file_contains_text(filepath, zf):
write_text_with_line_no(filepath, zf, extra_path_info)
elif zipfile.is_zipfile(filepath):
make_recursive_call_for_zip(filepath)
elif is_nested_zip(filepath, zf):
with zf.open(filepath, 'r') as f:
make_recursive_call_for_zip(f, create_extra_path_info(filepath))
# must open the nested zip file before checking otherwise doesn't give the correct result
def is_nested_zip(filename, zf):
with zf.open(filename, 'r') as f:
if zipfile.is_zipfile(f):
return True
return False
def is_zip_or_nested_zip(filename, zf):
return zipfile.is_zipfile(filename) or is_nested_zip(filename, zf)
# os.path.isdir() does not work for dirs inside zips so we write our own
def is_dir(filepath):
return filepath.endswith(PATH_SEPARATOR)
def file_contains_text(filename, zf):
with zf.open(filename, 'r') as f:
if search_string.encode() in f.read():
return True
return False
def write_text_with_line_no(filename, zf, extra_path_info):
with zf.open(filename, 'r') as f, open(outputfile, 'a+') as op:
for (i, line) in enumerate(f):
if search_string.encode() in line:
op.write(f'{extra_path_info + PATH_SEPARATOR + filename}: line{str(i+1)} : {line.decode()}')
# extra_path_info makes sure when accessing nested zips the path up to the nested zip is preserved
def create_extra_path_info(filepath):
return PATH_SEPARATOR.join(filepath.split(PATH_SEPARATOR)[:-1])
def make_recursive_call_for_zip(filepath, extra_path_info=''):
with zipfile.ZipFile(filepath, 'r') as zf:
for filename in zf.namelist():
find_string_in_nested_zip(filename, zf, extra_path_info)
find_string_in_nested_zip(rootzipfile)