递归编号目录:如何为目录树批量重命名编号?
递归批量重命名目录树的实用方案
刚好我前段时间刚处理过类似的批量目录重命名需求,给你几个不同平台的实用方案,完全可以自定义你想要的编号/标记规则,不管是纯数字、字母还是混合形式都能搞定:
一、Bash 脚本(Linux/macOS 适用)
核心思路是从最深层目录开始遍历(避免父目录改名后子目录路径失效),然后按自定义规则生成新名称。
下面是一个基础的数字编号脚本,你可以直接修改前缀、编号格式:
#!/bin/bash # 自定义配置:前缀、起始编号、数字位数 PREFIX="doc_" START_NUM=1 NUM_DIGITS=3 # 深度优先遍历所有目录(从最深到最浅) find . -type d -depth | while read dir; do # 跳过当前根目录本身 if [ "$dir" = "." ]; then continue fi # 获取父目录路径 parent_dir=$(dirname "$dir") # 生成带固定位数的编号名称 new_name="${PREFIX}$(printf "%0${NUM_DIGITS}d" $START_NUM)" # 执行重命名 mv "$dir" "$parent_dir/$new_name" # 编号递增 START_NUM=$((START_NUM + 1)) done
自定义规则示例:
- 改成字母序列:可以加一个生成字母的函数,比如把
new_name替换成:# 生成a、b、c...aa、ab这样的字母序列 get_letter() { local num=$1 local letters="" while [ $num -gt 0 ]; do num=$((num - 1)) letters=$(printf "\\$(printf '%03o' $((97 + num % 26)))")$letters num=$((num / 26)) done echo "$letters" } new_name="${PREFIX}$(get_letter $START_NUM)"
二、PowerShell 脚本(Windows 适用)
Windows下用PowerShell同样可以实现深度优先遍历,语法更贴近自然语言:
# 自定义配置 $prefix = "project_" $startNum = 1 $numDigits = 3 # 深度优先遍历目录(按路径倒序实现从深到浅) Get-ChildItem -Directory -Recurse | Sort-Object -Property FullName -Descending | ForEach-Object { $parentDir = $_.DirectoryName # 生成固定位数的编号名称 $newName = "$prefix$($startNum.ToString('D' + $numDigits))" $newPath = Join-Path -Path $parentDir -ChildPath $newName # 执行重命名(可以先换成Write-Host测试输出) Rename-Item -Path $_.FullName -NewName $newPath $startNum++ }
自定义字母序列:
把$newName改成下面的代码,就能生成a、b...aa这样的序列:
function Get-LetterSequence { param([int]$num) $letters = @() while ($num -gt 0) { $num-- $letters += [char](96 + $num % 26) $num = [math]::Floor($num / 26) } return -join $letters[($letters.Count-1)..0] } $newName = "$prefix$(Get-LetterSequence $startNum)"
三、Python 脚本(跨平台,灵活性最高)
如果需要更复杂的规则(比如结合目录原属性、自定义逻辑),Python是最佳选择,而且跨平台通用:
import os def get_letter_sequence(num): """生成a、b...aa、ab这样的字母序列""" letters = [] while num > 0: num -= 1 letters.append(chr(ord('a') + num % 26)) num = num // 26 return ''.join(reversed(letters)) def recursive_rename(root_dir, prefix="folder_", start_num=1, use_letters=False): # topdown=False 强制从最深层目录开始遍历 for root, dirs, files in os.walk(root_dir, topdown=False): # 可以在这里添加排序逻辑,比如按创建时间排序 # dirs.sort(key=lambda d: os.path.getctime(os.path.join(root, d))) for dir_name in dirs: old_path = os.path.join(root, dir_name) # 根据配置生成新名称 if use_letters: new_name = f"{prefix}{get_letter_sequence(start_num)}" else: # 三位数字编号 new_name = f"{prefix}{start_num:03d}" new_path = os.path.join(root, new_name) # 先打印测试,确认无误后再取消注释os.rename # print(f"Renaming: {old_path} -> {new_path}") os.rename(old_path, new_path) start_num += 1 # 使用示例:当前目录作为根目录,启用字母序列 if __name__ == "__main__": recursive_rename(".", prefix="asset_", start_num=1, use_letters=True)
重要注意事项
- 必须深度优先遍历:如果从根目录开始改,父目录改名后子目录的路径会失效,导致重命名失败。
- 先测试再执行:建议先把重命名代码换成打印输出(比如bash的
echo mv、Python的print),确认新名称符合预期后再执行实际重命名。 - 备份目录:批量操作有风险,执行前最好先备份整个目录树。
内容的提问来源于stack exchange,提问作者alien250
相关产品推荐
相关产品推荐

