在文件管理场景中,批量重命名是高频需求,比如统一修改日志文件后缀、按规则整理素材文件名等。C++标准库提供了文件系统和正则表达式相关组件,可以高效实现支持正则替换的多文件批量重命名功能。

实现核心思路
整个功能的实现可以分为四个核心步骤:
- 遍历目标目录下的所有文件,筛选出需要处理的文件
- 读取用户配置的正则匹配规则和替换规则
- 对每个文件名执行正则匹配,替换符合规则的部分生成新文件名
- 执行文件重命名操作,同时处理可能出现的异常
依赖的头文件
实现该功能需要引入以下C++标准库头文件:
#include <iostream> #include <filesystem> #include <regex> #include <string> #include <vector> #include <exception> // 命名空间简化代码书写 namespace fs = std::filesystem;
目录文件遍历实现
使用std::filesystem的目录迭代器可以遍历指定路径下的所有文件,这里需要注意区分文件和子目录,避免误处理目录:
// 获取目标目录下所有普通文件的路径
std::vector<fs::path> get_target_files(const std::string& dir_path) {
std::vector<fs::path> file_list;
try {
// 检查目录是否存在
if (!fs::exists(dir_path) || !fs::is_directory(dir_path)) {
std::cerr << "目标路径不存在或不是目录" << std::endl;
return file_list;
}
// 遍历目录内容
for (const auto& entry : fs::directory_iterator(dir_path)) {
// 只处理普通文件,跳过目录和特殊文件
if (fs::is_regular_file(entry.status())) {
file_list.push_back(entry.path());
}
}
} catch (const std::exception& e) {
std::cerr << "遍历目录失败: " << e.what() << std::endl;
}
return file_list;
}
正则替换逻辑实现
正则替换是核心功能,使用std::regex和std::regex_replace实现文件名的部分替换,支持捕获组等正则特性:
// 对单个文件名执行正则替换,返回新文件名
std::string regex_rename(const std::string& old_name, const std::string& pattern, const std::string& replace_str) {
try {
std::regex reg(pattern);
// 执行正则替换,匹配到的部分会被替换为指定字符串
std::string new_name = std::regex_replace(old_name, reg, replace_str);
return new_name;
} catch (const std::exception& e) {
std::cerr << "正则规则错误: " << e.what() << std::endl;
return old_name;
}
}
完整批量重命名实现
将前面的模块组合起来,实现完整的批量重命名功能,包含参数校验和结果反馈:
// 批量重命名主函数
// dir_path: 目标目录路径
// pattern: 正则匹配规则
// replace_str: 替换字符串
void batch_rename(const std::string& dir_path, const std::string& pattern, const std::string& replace_str) {
// 获取所有待处理文件
std::vector<fs::path> files = get_target_files(dir_path);
if (files.empty()) {
std::cout << "未找到需要处理的文件" << std::endl;
return;
}
int success_count = 0;
int fail_count = 0;
// 遍历处理每个文件
for (const auto& file_path : files) {
std::string old_name = file_path.filename().string();
// 执行正则替换得到新文件名
std::string new_name = regex_rename(old_name, pattern, replace_str);
// 如果文件名没有变化则跳过
if (new_name == old_name) {
continue;
}
// 构造新的完整路径
fs::path new_path = file_path.parent_path() / new_name;
// 检查新文件名是否已存在
if (fs::exists(new_path)) {
std::cerr << "重命名失败,新文件名已存在: " << old_name << " -> " << new_name << std::endl;
fail_count++;
continue;
}
// 执行重命名操作
try {
fs::rename(file_path, new_path);
std::cout << "重命名成功: " << old_name << " -> " << new_name << std::endl;
success_count++;
} catch (const std::exception& e) {
std::cerr << "重命名失败: " << old_name << " 错误原因: " << e.what() << std::endl;
fail_count++;
}
}
std::cout << "批量重命名完成,成功: " << success_count << " 个,失败: " << fail_count << " 个" << std::endl;
}
使用示例
以下是调用上述函数的示例,实现将目录下所有以log开头的文件替换为bak开头:
int main() {
// 目标目录,这里使用当前目录,也可以替换为其他路径如./test_dir
std::string target_dir = ".";
// 正则规则:匹配以log开头的文件名
std::string regex_pattern = "^log";
// 替换字符串:将匹配到的log替换为bak
std::string replace_content = "bak";
// 执行批量重命名
batch_rename(target_dir, regex_pattern, replace_content);
return 0;
}
注意事项
- 正则规则需要符合C++标准的正则语法,特殊字符需要正确转义
- 重命名前建议先备份文件,避免误操作导致文件丢失
- 如果目标目录包含大量文件,遍历和重命名过程可能需要一定时间,可添加进度提示
- 不同操作系统的文件系统对文件名大小写敏感度不同,正则规则需要适配对应系统特性