os.rename执行正则操作后报ValueError: embedded null byte错误求助
问题描述
运行Python脚本为文件添加后缀时,执行os.rename函数抛出ValueError: embedded null byte错误。脚本通过正则匹配文件扩展名,遍历目标目录为符合条件的文件名添加指定后缀,执行前打印的新旧路径显示正常,但路径中莫名混入空字节,尝试添加.encode("utf-8").strip()后仍未解决问题。
报错信息
Renaming chr1/tests/test-ch1.py to chr1/tests/test-ch1_ref.py... Traceback (most recent call last): File "/Users/eomiso/Workspace/miso-projects/scripts/append_ref_to_filename.py", line 18, in <module> os.rename(old_path, new_path) ValueError: embedded null byte
原代码
import os import re # Define the path to the directory containing the files target_dir = "chr1/tests" suffix = "_ref" # Compile a regular expression to match file extensions ext_pattern = re.compile(r"\.[^.]+$") for root, dirs, files in os.walk(target_dir): for filename in files: if ext_pattern.search(filename) and not filename.endswith(suffix): old_path = os.path.join(root, filename) ext = ext_pattern.search(old_path).group() new_path = os.path.join(root, ext_pattern.sub(f"{suffix}\\0", filename)) + ext print(f"Renaming {old_path} to {new_path}...") os.rename(old_path.strip(), new_path.strip())
问题原因与修复
核心问题
代码中ext_pattern.sub(f"{suffix}\\0", filename)是错误根源:在f-string中,\\0会被解析为空字节(\x00),而非正则表达式中引用整个匹配结果的语法。这导致生成的new_path包含空字节,触发os.rename的参数合法性校验错误。
修复方案
将正则替换中的\\0改为\\g<0>(规范的正则组引用方式),同时简化冗余的扩展名处理逻辑:
修改后的代码:
import os import re target_dir = "chr1/tests" suffix = "_ref" ext_pattern = re.compile(r"\.[^.]+$") for root, dirs, files in os.walk(target_dir): for filename in files: match = ext_pattern.search(filename) if match and not filename.endswith(suffix): old_path = os.path.join(root, filename) # 使用\\g<0>引用整个匹配的扩展名,避免生成空字节 new_filename = ext_pattern.sub(f"{suffix}\\g<0>", filename) new_path = os.path.join(root, new_filename) print(f"Renaming {old_path} to {new_path}...") os.rename(old_path, new_path)
额外优化点
- 直接在
filename上完成替换生成新文件名,再拼接路径,避免重复处理路径字符串 - 提前获取正则匹配对象,避免重复调用
ext_pattern.search,提升代码效率 - 移除不必要的
.strip()调用,防止误删文件名中合法的首尾空格(若存在)
内容的提问来源于stack exchange,提问作者Aesop
相关产品推荐
相关产品推荐

