Search code examples
windowsbatch-filecmdbatch-processingrenaming

How to rename a folder the same as the filename of the first file inside that folder using Windows batch programming?


I have a group of about 3,000 folders named XYZ-1 through XYZ-3000. Inside those folders are groups of image files and a description text file. Such as:

  • Property123_0001.jpg
  • Property123_0002.jpg
  • Property123_0003.jpg
  • ...
  • Property123_0085.jpg
  • Property123_0086.jpg
  • Z_Description.txt

The number of .jpg files differs in each folder, but there's always a single description file. Each directory's image files have a different name, for example `XYZ-1 might contain Property123, while XYZ-10 might contain Easement789.

I need to rename the folders containing the files after the "Property123" part of the .jpg files. Ideally I would truncate off the trailing digits and the underscore, but even if they were left on, it would be better than the XYZ-1 names.

I'm working on a batch file to do just that, but mine won't run and I can't figure out why.

Here's what I have:

for /d %%D in (*) do (
   set "_dir=%%D"
   set /a "_first=1"
   cd "%%D"
   for %%F in (*) do (
      if %_first%==1 set "_name=%%~nF"
      set /a "_first=0"
   )
   cd ..
   ren %_dir% %_name%
)

Unfortunately, when I run it, the command window just closes immediately. I tried putting a pause command at the end, but that didn't keep the window open. Nothing happens to the files/folders.

I've tried my syntax from a command line and everything looks OK. So I don't know what the problem is. Can I get a little help, please?


Solution

  • Try this:

    @echo off
    setlocal EnableDelayedExpansion
    for /d %%D in (*) do (
       set "_dir=%%D"
       set "_name=%%D"
       set /a "_first=1"
       cd "%%D"
       for %%F in (*) do (
          if !_first!==1 set "_name=%%~nF"
          set /a "_first=0"
       )
       cd ..
       ren !_dir! !_name!
    )
    

    You need to use setlocal EnableDelayedExpansion here, and use ! instead of % inside for loops.

    I also added set "_name=%%D" so it won't try to change a second folder to the first folders name if that folder doesn't contain files

    EDIT:

    also takes into consideration the underscore part:

    @echo off
    setlocal EnableDelayedExpansion
    for /d %%D in (*) do (
       set "_dir=%%D"
       set "_name=%%D"
       set /a "_first=1"
       cd "%%D"
       for %%F in (*) do (
          if !_first!==1 (
            set "_name=%%~nF"
            set /a "_first=0"
            if NOT "!_name!"=="!_name:_=!" (
              set "subfix=!_name:*_=!"
              for /f "delims=" %%B in ("!subfix!") do set "_name=!_name:_%%B=!"
            )
          )
       )
       cd ..
       ren !_dir! !_name!
    )