1

I have a folder full of JPG files called input.

input\1.jpg
input\2.jpg
input\3.jpg

Goal is

input\01.jpg
input\02.jpg
input\03.jpg

Have a mostly functioning script. Just won't work when I set it to a subfolder.

setlocal disabledelayedexpansion
set "sourcedir=input"
for /F "EOL=| delims=" %%G in ('dir /B /A-D "%sourcedir%\*.jpg" 2^>nul') do (
    set "basename=0000%%~nG"
    setLocal enabledelayedexpansion
    ren "%%G" "!basename:~-2!.new"
    endlocal
)
:: for /r %%f in (input\*.new) do ren "%%f" *.jpg

Can not figure out why it will not work in a sub directory.
if I set sourcedir= to nothing, it works fine in the root directory.

all I get is The system cannot find the file specified. when I run this.

aschipfl
  • 33,626
  • 12
  • 54
  • 99
SuperMar1o
  • 670
  • 8
  • 23

2 Answers2

1

The value of %sourcedir% is a relative path (input), which is going to be related to the current working directory (%CD%), which is not the same as the parent directory of the script (which is referred to by %~dp0.).

The dir /B command (without /S option) always returns pure file names, even when you specify a longer path (like %sourcedir%\*.jpg), so %%G is assumed to be in the current working directory. Hence you will need to use %sourcedir%\%%G instead.

Here is a working suggestion:

@echo off
setlocal EnableExtensions DisableDelayedExpansion
rem // Specify sub-directory of parent directory of this script:
set "sourcedir=%~dp0input"
for /F "eol=| delims=" %%G in ('dir /B /A:-D "%sourcedir%\*.jpg" 2^> nul') do (
    rem /* Avoid expansion of `for` meta-variables during delayed expansion in order to
    rem    avoid loss of `!` (though this is not an issue with the file names at hand): */
    set "filename=%%G" & set "basename=0%%~nG" & set "ext=%%~xG"
    setlocal EnableDelayedExpansion
    ren "!sourcedir!\!filename!" "!basename:~-2!!ext!"
    endlocal
)

To avoid multiple specifications of the directory path use cd /D to specify it once:

@echo off
setlocal EnableExtensions DisableDelayedExpansion
rem // Specify sub-directory of parent directory of this script:
set "sourcedir=%~dp0input"
cd /D "%sourcedir%" && (
    for /F "eol=| delims=" %%G in ('dir /B /A:-D "*.jpg" 2^> nul') do (
        set "filename=%%G" & set "basename=0%%~nG" & set "ext=%%~xG"
        setlocal EnableDelayedExpansion
        ren "!filename!" "!basename:~-2!!ext!"
        endlocal
    )
)

Or alternatively pushd/popd:

@echo off
setlocal EnableExtensions DisableDelayedExpansion
rem // Specify sub-directory of parent directory of this script:
set "sourcedir=%~dp0input"
pushd "%sourcedir%" && (
    for /F "eol=| delims=" %%G in ('dir /B /A:-D "*.jpg" 2^> nul') do (
        set "filename=%%G" & set "basename=0%%~nG" & set "ext=%%~xG"
        setlocal EnableDelayedExpansion
        ren "!filename!" "!basename:~-2!!ext!"
        endlocal
    )
    popd
)
aschipfl
  • 33,626
  • 12
  • 54
  • 99
0

the answer was a duh moment. PUSHD

Pushd input
setlocal disabledelayedexpansion
set "sourcedir=input"
for /F "EOL=| delims=" %%G in ('dir /B /A-D "*.jpg" 2^>nul') do (
    set "basename=0000%%~nG"
    setLocal enabledelayedexpansion
    ren "%%G" "!basename:~-2!.new"
    endlocal
)
popd

I am sure there are more elegant methods. But this worked great.

Bonus compact alternative method

SetLocal EnableDelayedExpansion
for %%j in (input\*.jpg) do (
    set fn=00000%%~nj
    set fn=!fn:~-2!
    ren "%%j" "!fn!%%~xj"
)
SuperMar1o
  • 670
  • 8
  • 23
  • 1
    Your compact method can be dangerous when the renamed files still match the given pattern (`*.jpg`), because files might be attempted to become renamed twice; although this might not be an issue in the situation at hand, I recommend to prefer `for /F` + `dir /B` over `for`, because the former builds the complete file list in advance, but the latter does not. Take a look at this thread for further details: [At which point does `for` or `for /R` enumerate the directory (tree)?](/q/31975093) – aschipfl Dec 10 '20 at 09:45
  • Yeah, you had a good point. The compact method had a tendency to break things lol. Which would make sense now. Thanks for the response! – SuperMar1o Dec 11 '20 at 01:59