You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用正则表达式批量重命名文件并保留关联文件名规则

批量重命名照片:保留原片与编辑版关联,按文件夹独立编号

场景与需求

已通过Exif Sorter将照片整理为%UserProfile%\Photos\%year%\%month%\%day%的层级文件夹结构,每个日期文件夹内的照片文件名格式杂乱,示例如下:

IMG_0001.jpg
ZMGM00002.jpg
ZMGM00003 (Edited).jpg
ZMGM00003.jpg
IMG_0002 (Edited).jpg
IMG_0002.jpg
IMG_0004.jpg

需要实现:

  1. 统一重命名为DSC_XXXX.jpg格式,原片与对应编辑版共享同一编号(如DSC_0002.jpg和DSC_0002 (Edited).jpg)
  2. 每个日期文件夹内的编号独立从1开始重新计数
  3. 支持批量处理近8万张照片,遍历上千个文件夹

当前使用RegexRenamer的问题:用正则^(\D+)(_)?(\d+)(Edited)?替换为DCS_$#$4会导致所有文件连续编号,丢失原片与编辑版的关联,结果不符合需求:

DSC_0001.jpg
DSC_0002.jpg
DSC_0003 (Edited).jpg
DSC_0004.jpg
DSC_0005 (Edited).jpg
DSC_0006.jpg
DSC_0007.jpg

解决方案

Windows 方案:PowerShell 脚本(原生支持,推荐)

PowerShell可遍历所有日期文件夹,按文件夹分组处理,自动识别原片与对应编辑版,再统一分配编号。

脚本代码

# 替换为你的照片库根路径
$rootPath = "$env:UserProfile\Photos"

# 遍历所有年/月/日层级的文件夹
Get-ChildItem -Path $rootPath -Directory -Recurse | ForEach-Object {
    $folder = $_.FullName
    Write-Host "处理文件夹: $folder"

    # 获取当前文件夹内的照片文件(可扩展后缀如.png/.raw等)
    $photos = Get-ChildItem -Path $folder -File -Include "*.jpg", "*.jpeg" | Sort-Object Name

    # 分组:提取文件核心编号,将原片和编辑版归为同一组
    $groups = $photos | Group-Object -Property {
        $name = $_.BaseName
        # 移除(Edited)后缀
        $coreName = $name -replace "\s*\(Edited\)$", ""
        # 提取数字编号(兼容带/不带下划线的文件名)
        if ($coreName -match "\d+") { $matches[0] } else { $coreName }
    }

    # 为每组分配统一编号,执行重命名
    $counter = 1
    foreach ($group in $groups) {
        $padNumber = $counter.ToString("0000")
        foreach ($file in $group.Group) {
            $isEdited = $file.BaseName -match "\s*\(Edited\)$"
            $newBaseName = if ($isEdited) { "DSC_$padNumber (Edited)" } else { "DSC_$padNumber" }
            $newPath = Join-Path -Path $folder -ChildPath "$newBaseName$($file.Extension)"
            
            # 测试阶段可注释下面一行,用Write-Host $newPath预览结果
            Rename-Item -Path $file.FullName -Destination $newPath -Force
        }
        $counter++
    }
}

使用说明

  1. 打开PowerShell,修改$rootPath为你的照片库根目录
  2. 先注释Rename-Item行,运行脚本预览重命名结果,确认无误后再取消注释执行实际重命名
  3. 脚本会自动遍历所有日期文件夹,每个文件夹内编号从1开始,原片与编辑版共享编号

Windows 方案:改进RegexRenamer逻辑(适合小批量)

若坚持使用RegexRenamer,需分三步处理:

  1. 标记关联组:
    • 匹配带(Edited)的文件:用正则^(.*?)(\d+)(.*)\(Edited\)(.*)$,替换为$2_TEMP_EDITED$4
    • 匹配原片文件:用正则^(.*?)(\d+)(.*)$,替换为$2_TEMP_ORIG$3
  2. 按标记分组编号:按文件名前缀的数字分组,给每组分配DSC_XXXX编号
  3. 恢复后缀:将_TEMP_EDITED替换回 (Edited),删除_TEMP_ORIG标记

macOS 方案:Shell 脚本

通过bash/zsh脚本实现遍历与分组编号,逻辑与PowerShell一致:

脚本代码

#!/bin/bash

# 替换为你的照片库根路径
ROOT_PATH="$HOME/Photos"

# 遍历所有日期文件夹
find "$ROOT_PATH" -type d | while read -r folder; do
    echo "处理文件夹: $folder"
    cd "$folder" || continue

    # 分组:将原片与编辑版按核心编号归类
    declare -A file_groups
    for file in *.jpg *.jpeg; do
        if [[ -f "$file" ]]; then
            base=$(basename "$file" .${file##*.})
            # 移除(Edited)后缀
            core_base=${base%% *(Edited)}
            # 提取数字编号
            if [[ "$core_base" =~ ([0-9]+) ]]; then
                core_num=${BASH_REMATCH[1]}
            else
                core_num="$core_base"
            fi
            file_groups["$core_num"]+="$file "
        fi
    done

    # 为每组分配编号并执行重命名
    counter=1
    for core_num in "${!file_groups[@]}"; do
        pad_num=$(printf "%04d" "$counter")
        files=${file_groups["$core_num"]}
        for file in $files; do
            base=$(basename "$file" .${file##*.})
            if [[ "$base" == *"(Edited)" ]]; then
                new_name="DSC_${pad_num} (Edited).${file##*.}"
            else
                new_name="DSC_${pad_num}.${file##*.}"
            fi
            # 测试阶段可注释下面一行,用echo "重命名 $file -> $new_name"预览
            mv -v "$file" "$new_name"
        done
        ((counter++))
    done
done

使用说明

  1. 打开终端,创建rename_photos.sh文件并粘贴代码,修改ROOT_PATH
  2. 赋予执行权限:chmod +x rename_photos.sh
  3. 先注释mv -v行预览结果,确认无误后执行实际重命名

内容的提问来源于stack exchange,提问作者bananakid

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.31 16:10:25