Python补丁文件备份替换脚本索引越界错误修复求助
首先来看你遇到的IndexError问题:你的dir_list里有4个元素(对应两个目标目录下的2个文件,一共4个文件路径),但content列表只有2个文件名。当你用range(0, len(dir_list))循环时,dst_ind会取到0、1、2、3,而content的索引只有0和1,所以当dst_ind=2时就会触发索引越界错误。
问题出在你试图用循环索引直接关联content和dir_list,但两者的长度不匹配——dir_list是content长度的N倍(N是目标目录的数量),这种索引关联的逻辑本身就不成立。
解决方案:保存文件名与目标目录的对应关系
我们可以修改代码,在收集文件信息时,同时保存文件名和所在目录,这样后续复制时就能直接找到对应的补丁文件,不需要依赖索引关联。
修复后的完整代码
#!/usr/bin/env python import os import datetime import shutil # 读取需要替换的文件名列表 with open('filenames.txt') as f: content = [x.strip() for x in f.readlines()] print('File contents:') print(content) # 生成备份后缀(格式:_ddMonyyyy) suffix = datetime.datetime.now().strftime("_%d%b%Y") approot = '/home/saurabh/testbed/dest_dir/' source_dir = '/home/saurabh/testbed/patch_dir/' # 保存(文件名, 目标目录)的元组列表,替代原来的dir_list file_info_list = [] print('\n' + 'Renaming files present at:') for root, dirs, files in os.walk(approot): # 只处理content中存在的文件名(精确匹配,不需要fnmatch) for filename in files: if filename in content: file_path = os.path.join(root, filename) print(file_path) # 创建备份文件 backup_file = f"{file_path}{suffix}" os.rename(file_path, backup_file) # 记录文件名和目标目录 file_info_list.append( (filename, root) ) print("\n" + "Backup of all files complete!") print(f'Backup of {len(file_info_list)} files taken recursively') print(f'Number of files mentioned in text file: {len(content)}\n') # 验证找到的文件数量是否符合预期(每个目标目录对应content中的所有文件) expected_count = len(content) * 2 # 对应app_dir_1和app_dir_2两个目录 if len(file_info_list) == expected_count: print("Retrofitted components will be copied to their respective directories") # 遍历每个需要替换的文件信息 for filename, dst_dir in file_info_list: src_file = os.path.join(source_dir, filename) print(f"{src_file}\t{dst_dir}") # 执行复制操作(取消注释即可生效) # shutil.copy2(src_file, dst_dir) else: print(f"Warning: Found {len(file_info_list)} files, expected {expected_count}")
关键修改点说明
替换
dir_list为file_info_list:
不再只保存目录路径,而是保存(文件名, 目录路径)的元组,这样后续复制时能直接通过文件名找到补丁目录中的对应文件,彻底避免索引越界问题。简化文件名匹配逻辑:
因为你的content是精确的文件名列表,不需要用fnmatch,直接用filename in content判断即可,代码更简洁高效。优化预期数量判断:
用变量expected_count明确表示预期的文件数量,代码可读性更强,后续切换到生产环境(12个目录)时,只需要修改expected_count = len(content) * 12即可。使用f-string格式化输出:
替换原来的字符串拼接,代码更清晰易读。
运行修复后的代码,就能得到你期望的输出,并且成功完成补丁文件的复制操作。
内容的提问来源于stack exchange,提问作者user9652688

