1

This command in cmd renames all files in the current directory

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

But I need to get the current subdirectory name (folder name only) and append that to the %a

It should loop through all the subdirectories in the parent folder.

I have Path C:\Temp\Photos_ToRename with following folders and files

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)

.....

jussamen
  • 13
  • 5
  • 2
    I recently answered a similar question here: https://stackoverflow.com/a/64601339/1024832. It basically flattens the directory structure by moving the directory names into the filename, which I think is exactly what you're trying to do. As mentioned in the caveats, only run it on a directory that you have a copy/backup of. – Marc Nov 17 '20 at 02:52
  • I changed the [tag:batch-rename] to [tag:batch-file] because I think that is what you have meant; if I am wrong and you do not want to use a batch file, simple remove that tag… – aschipfl Nov 17 '20 at 09:14
  • DOS doesn't have `for /f`. It's a command in Windows cmd which is a [completely different thing](https://superuser.com/a/1411173/241386). Don't use DOS when you're talking about Windows cmd – phuclv Nov 19 '20 at 04:24

2 Answers2

0

I think this should do the trick:

@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%

This keeps each file in its current folder, but renames it as folder_subfolder_filename.

I had to add that if, because otherwise with an empty folder variable it assigned \=_ to it.

I first store the current path in order to remove that from each file's full path, and then prepend the relative path to the name.

Andrew
  • 7,602
  • 2
  • 34
  • 42
0

This should do the trick without string manipulation and with iteration of the needed directory hierarchy depth only ‐ code for direct usage in Command Prompt:

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)

Code for usage within a batch file (with comments):

@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
    )
)
aschipfl
  • 33,626
  • 12
  • 54
  • 99