#!/usr/bin/env python3
"""
批量重命名文件并保留原始扩展名。
用法:
python rename_keep_ext.py <目录路径> <旧文本> <新文本> [--dry-run]
示例:
将当前目录下所有文件名中的 "photo" 替换为 "image":
python rename_keep_ext.py . photo image
预览替换效果(不实际执行):
python rename_keep_ext.py . photo image --dry-run
"""
import os
import sys
import argparse
def parse_arguments():
"""解析命令行参数"""
parser = argparse.ArgumentParser(
description="批量重命名文件,仅修改文件名主体部分,保留原始扩展名。"
)
parser.add_argument(
"directory",
help="要处理的目录路径"
)
parser.add_argument(
"old_text",
help="要被替换的旧文本(区分大小写)"
)
parser.add_argument(
"new_text",
help="替换后的新文本"
)
parser.add_argument(
"--dry-run",
action="store_true",
help="预览模式:只显示将要发生的操作,不实际执行重命名"
)
return parser.parse_args()
def batch_rename(directory, old_text, new_text, dry_run=False):
"""
批量重命名目录中的文件。
规则:
- 只修改文件名的主干部分(不含扩展名)。
- 如果替换后的文件名与现有文件冲突,则跳过该文件并输出警告。
- 如果文件名中不包含 old_text,则跳过。
"""
if not os.path.isdir(directory):
print(f"错误:目录 '{directory}' 不存在或不是一个有效的目录。", file=sys.stderr)
sys.exit(1)
renamed_count = 0
skipped_count = 0
# 获取目录下所有文件(不包括子目录)
entries = os.listdir(directory)
files = [f for f in entries if os.path.isfile(os.path.join(directory, f))]
if not files:
print("目录中没有找到任何文件。")
return
print(f"在目录 '{directory}' 中查找包含 '{old_text}' 的文件...\n")
for filename in files:
# 分离文件名主干和扩展名
name_part, ext = os.path.splitext(filename)
# 如果主干中不包含旧文本,跳过
if old_text not in name_part:
continue
# 执行替换(区分大小写)
new_name_part = name_part.replace(old_text, new_text)
new_filename = new_name_part + ext # 保留原始扩展名
# 如果新文件名没有变化,跳过(理论上不会发生,因为 old_text 在 name_part 中)
if new_filename == filename:
continue
old_path = os.path.join(directory, filename)
new_path = os.path.join(directory, new_filename)
# 检查目标文件是否已存在(避免覆盖)
if os.path.exists(new_path):
print(f"⚠ 跳过:目标文件已存在 -> {new_filename} (源文件: {filename})")
skipped_count += 1
continue
if dry_run:
print(f"[预览] 将重命名: '{filename}' -> '{new_filename}'")
else:
try:
os.rename(old_path, new_path)
print(f"✔ 已重命名: '{filename}' -> '{new_filename}'")
renamed_count += 1
except OSError as e:
print(f"✖ 重命名失败: {filename} -> {new_filename},错误: {e}", file=sys.stderr)
skipped_count += 1
print(f"\n操作完成。")
print(f" 成功重命名: {renamed_count} 个文件")
if skipped_count > 0:
print(f" 跳过: {skipped_count} 个文件(冲突或错误)")
def main():
args = parse_arguments()
batch_rename(
directory=args.directory,
old_text=args.old_text,
new_text=args.new_text,
dry_run=args.dry_run
)
if __name__ == "__main__":
main()
使用说明
基本用法
将脚本保存为 rename_keep_ext.py,然后在终端运行:

python rename_keep_ext.py <目录路径> <旧文本> <新文本>
示例:将 /home/user/photos 目录下所有文件名中的 2024_ 替换为 2025_:
python rename_keep_ext.py /home/user/photos 2024_ 2025_
预览模式(安全测试)
添加 --dry-run 参数可以只显示将要进行的重命名操作,而不实际修改文件:
python rename_keep_ext.py /home/user/photos 2024_ 2025_ --dry-run
功能特点
- 保留扩展名:只修改文件名的主干部分(如
document.txt中的document) - 区分大小写:
Photo和photo被视为不同字符串 - 冲突检测:如果新文件名已存在,会自动跳过并提示
- 详细输出:显示每个文件的重命名结果或跳过原因
常见场景
| 场景 | 命令示例 |
|---|---|
| 替换日期前缀 | python rename_keep_ext.py . "2024_" "2025_" |
| 修改项目名称 | python rename_keep_ext.py ./docs "draft" "final" |
| 清理文件名 | python rename_keep_ext.py . " - Copy" "" |
| 批量添加后缀 | 注意:此脚本不支持直接添加,需配合其他方法 |
如果需要更复杂的模式匹配(如正则表达式),可以扩展脚本或使用专门的工具(如 rename 命令或 sed)。
版权声明:NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
足球直播
足球直播
足球直播
足球直播
足球直播
英超直播
英超直播
英超直播
英超直播
英超直播
篮球直播
篮球直播
篮球直播
篮球直播
篮球直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
中超直播
中超直播
中超直播
中超直播
中超直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
足球直播
足球直播
足球直播
足球直播
足球直播
英超直播
英超直播
英超直播
英超直播
英超直播
篮球直播
篮球直播
篮球直播
篮球直播
篮球直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
中超直播
中超直播
中超直播
中超直播
中超直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播