CMD 迭代并递归重命名所有文件名并将当前子目录文件夹附加到当前文件名

CMD to iterate and recursively rename all filenames and append the current subdirectory folder to the current filename

cmd中的这个命令重命名当前目录下的所有文件

for /f "tokens=*" %a in ('dir /b') do ren "%a" "00_%a"

但我需要获取当前子目录名称(仅文件夹名称)并将其附加到 %a

它应该遍历 parent 文件夹中的所有子目录。

我的路径 C:\Temp\Photos_ToRename 包含以下文件夹和文件

NVA-1234 (this is a subdirectory name)
--- IMG_0999.jpg (rename to NVA-1234_IMG_0999.jpg)
--- IMG_0989.jpg (rename to NVA-1234_IMG_0989.jpg)
--- IMG_0979.jpg (rename to NVA-1234_IMG_0979.jpg)

NVS-3456 (this is a subdirectory name)
--- IMG_1999.jpg (rename to NVS-3456_IMG_1999.jpg)
--- IMG_1989.jpg (rename to NVS-3456_IMG_1989.jpg)
--- IMG_1979.jpg (rename to NVS-3456_IMG_1979.jpg)

NVS-3359 (this is a subdirectory name)
--- IMG_2999.jpg (rename to NVS-3359_IMG_2999.jpg)
--- IMG_2989.jpg (rename to NVS-3359_IMG_2989.jpg)
--- IMG_2979.jpg (rename to NVS-3359_IMG_2979.jpg)

.....

我认为这应该可以解决问题:

@echo off
set root=%~dp0
for /f "tokens=*" %%a in ('dir /b /s') do call :process "%%a"
exit /b

:process
set fullfolder=%~dp1
call set folder=%%fullfolder:%root%=%%
if not %folder%x==x call set folder=%%folder:\=_%%
set newfile=%folder%%~nx1
ren %1 %newfile%

这会将每个文件保留在其当前文件夹中,但将其重命名为 folder_subfolder_filename。

我不得不添加 if,因为否则它会为空文件夹变量分配 \=_

我首先存储当前路径,以便从每个文件的完整路径中删除该路径,然后添加名称的相对路径。

这应该可以在没有字符串操作和只迭代所需的目录层次结构深度的情况下完成 - 在命令提示符中直接使用的代码:

for /D %J in ("C:\Temp\Photos_ToRename\*") do @pushd "%~J" && ((for /F "delims= eol=|" %I in ('dir /B /A:-D-H-S "*.jpg"') do @ren "%I" "%~nxJ_%I") & popd)

批处理文件中的使用代码(带注释):

@echo off
rem // Iterate only the required directory hierarchy depth:
for /D %%J in ("C:\Temp\Photos_ToRename\*") do (
    rem // Change into the currently iterated sub-directory:
    pushd "%%~J" && (
        rem /* Iterate through matching files; the `for /F` loop together with `dir` is
        rem    mandatory here and cannot be replaced by a simple standard `for` loop like
        rem    `for %%I in ("*.jpg") do`, because then, files might become renamed twice
        rem    since `for` does not build the complete file list prior to looping, but
        rem    `for /F` does as it awaits the full output of the `dir` command: */
        for /F "delims= eol=|" %%I in ('dir /B /A:-D-H-S "*.jpg"') do (
            rem // Actually rename the currently iterated file:
            ren "%%I" "%%~nxJ_%%I"
        )
        rem // Return from sub-directory:
        popd
    )
)