0

I want to create a batch script to rename files in a folder. I want to uppercase the first letter of each word in files names, for every files extensions. I consider a space, an underscore or a parenthesis as a delimiter between words.

For example:

24 true STORIES.txt -> 24 True Stories.txt    
age of empire (full version).exe -> Age Of Empire (Full Version).exe    
italian_food_in_30_recipes.pdf -> Italian_Food_In_30_Recipes.pdf    
NEW_YORK_CITY.jpeg -> New_York_City.jpeg    
the white dog.mp3 -> The White Dog.mp3

I found related posts about this, as @Squashman noticed, but I can't write a full script. Here are my first steps:

@ECHO OFF
SETLOCAL ENABLEDELAYEDEXPANSION

:: Input
SET /P DIR="Path to folder: "

:: Check the last character in the user input path
IF NOT !DIR:~-1! == "\" SET DIR=!DIR!\

:: Scan files in input folder
FOR %%F IN (%DIR%*) DO (
    SET "BASENAME=%%~NXF"    
    SET "NAME=%%~NXF"
    SET "F=TRUE"
    SET "NEWNAME="
    SET "DELIM=FALSE"
    SET "UNDERSCORE=_"
    SET "SPACE= "
    SET "PARENTHESIS=("
    CALL :CONVERT
)

:CONVERT

:: Lowercase
FOR %%A IN (a b c d e f g h i j k l m n o p q r s t u v w x y z) DO (
    SET "NAME=!NAME:%%A=%%A!"
   )   
)

:: Uppercase
SET "L=!NAME:~0,1!"
IF %F% == TRUE (
  SET "INITIAL=!L!"  
  FOR %%I IN (A B C D E F G H I J K L M N O P Q R S T U V W X Y Z) DO SET INITIAL=!INITIAL:%%I=%%I!
  SET NEWNAME=!NEWNAME!!INITIAL!
) ELSE (
  SET NEWNAME=!NEWNAME!!L!
)

:: Detect delimiter
IF "!L!" == "!UNDERSCORE" (
    SET "DELIM=TRUE"    
) ELSE (
    SET "DELIM=FALSE"   
)
IF "!L!" == "!SPACE!" (
    SET "DELIM=TRUE"    
) ELSE (
    SET "DELIM=FALSE"   
)    
IF !DELIM! == TRUE (
  SET "F=TRUE"
) ELSE (
  SET "F=FALSE"
)

:: Output
SET "NAME=!NAME:~1!"
IF DEFINED NAME GOTO CONVERT
IF NOT %DIR%!BASENAME! == %DIR%!NEWNAME! REN "%DIR%!BASENAME!" "!NEWNAME!"

:: End
EXIT /B

This return me:

24 True Stories.txt -> ok
Age Of Empire (full Version).exe -> not ok
Italian_food_in_30_recipes.pdf -> not ok
New_york_city.jpeg -> not ok
The White Dog.mp3 -> ok

How can I merge/combine severals if conditions (underscore, space, parenthesis...) ?

If I switch their order in script, result isn't the same. I don't find an easy explanation about logical operators to use an or statement like if "!L!" == "!UNDERSCORE!" or "!L!" == "!SPACE!" or "!L!" == "!PARENTHESIS!".

GeoGyro
  • 487
  • 12
  • 32
  • 1
    Well I can see which [Question](https://stackoverflow.com/questions/25199066/rename-all-files-in-folder-to-uppercase-with-batch) you took your code from which uppercases everything. I think you want this [post](https://stackoverflow.com/questions/48859587/bat-file-renaming-folders-changing-first-letter-of-every-word-to-uppercase) which does the Proper case case your want. This one does folder names but is easily converted to do it with file names. – Squashman Oct 26 '21 at 21:54
  • Thanks for your advice, I try this method and have updated my original post. – GeoGyro Oct 27 '21 at 19:25
  • The code link I gave you assumes everything is already lower case and then upper cases the first letter. You will need another `FOR` loop to lower case everything first. – Squashman Oct 27 '21 at 20:49
  • Unfortunately the code I linked to also has some bad coding practices. As a best practice all literal string comparisons should use quotes for the comparison. A space is a command delimiter. So if you need to see if something is equal to a space you need to use quotes. `IF "!L!" == "!SPACE!"` – Squashman Oct 27 '21 at 20:52
  • It's a good way. I've updated my post. It seems to be almost good, just a last issue with underscore and blank space delimiter. – GeoGyro Oct 28 '21 at 14:52

1 Answers1

0

I improved my script to detect underscores, spaces and parenthesis as delimiters. It's close to be the expected behaviour.

@ECHO OFF
SETLOCAL ENABLEDELAYEDEXPANSION

:: Input
SET /P DIR="Path to folder: "

:: Check the last character in the user input path
IF NOT !DIR:~-1! == "\" SET DIR=!DIR!\

:: Scan files in input folder
FOR %%F IN (%DIR%*) DO (
    SET "BASENAME=%%~NXF"    
    SET "NAME=%%~NXF"
    SET "F=TRUE"
    SET "NEWNAME="
    SET "DELIM=FALSE"  
    SET "UNDERSCORE=_"
    SET "SPACE= "
    SET "PARENTHESIS=("
    CALL :CONVERT
)

:CONVERT

:: Lowercase
FOR %%I IN (a b c d e f g h i j k l m n o p q r s t u v w x y z) DO SET "NAME=!NAME:%%I=%%I!"   

:: Uppercase
SET "L=!NAME:~0,1!"
IF %F% == TRUE (
    SET "INITIAL=!L!"
    FOR %%I IN (A B C D E F G H I J K L M N O P Q R S T U V W X Y Z) DO SET INITIAL=!INITIAL:%%I=%%I!
    SET NEWNAME=!NEWNAME!!INITIAL!
    SET "DELIM=FALSE"
) ELSE (
    SET NEWNAME=!NEWNAME!!L!
)

:: Detect delimiter
IF "!L!" == "!UNDERSCORE!" SET "DELIM=TRUE"

IF "!L!" == "!SPACE!" SET "DELIM=TRUE"

IF "!L!" == "!PARENTHESIS!" SET "DELIM=TRUE"

IF !DELIM! == TRUE (
    SET "F=TRUE"
) ELSE (
    SET "F=FALSE"
)

:: Output
SET "NAME=!NAME:~1!"
IF DEFINED NAME GOTO CONVERT
IF NOT %DIR%!BASENAME! == %DIR%!NEWNAME! REN "%DIR%!BASENAME!" "!NEWNAME!"

:: End
EXIT /B

When I run this I still have an issue on the last file name:

24 true STORIES.txt -> 24 True Stories.txt    
age of empire (full version).exe -> Age Of Empire (Full Version).exe    
italian_food_in_30_recipes.pdf -> Italian_Food_In_30_Recipes.pdf    
NEW_YORK_CITY.jpeg -> New_York_City.jpeg
the white dog.mp3 -> The White Dog.mp3
The White Dog.mp3 -> The White Dog.mp3a=a

A suffix a=a is added to the last file name, after extension. You will also notice that the last file name is renamed twice. I found this documentation (8.3 Filename bug - a single command can rename the same file twice!) about this behaviour but I dont understand how to solve this bug.

Any ideas ?

GeoGyro
  • 487
  • 12
  • 32