:: BY Alex V | Release 08/02/2017 | https://pastebin.com/raw/dhzkny3h | bulk_rename.bat --- Renames Files in a Folder :: USE AT YOUR OWN RISK!!!!! NO WARRANTY. NO SUPPORT. NO GUARANTEE @echo off && setlocal EnableDelayedExpansion EnableExtensions :: go to the start of the function calls goto START_SCRIPT %* goto :eof :HARDCODED_INPUT :: Hardcoded Variables ::::::::::::::: :: Location where you'd like to rename the files. if not defined bulkr_dir_with_files_to_rename ^ set "bulkr_dir_with_files_to_rename=" :: String that you would like replaced. if not defined bulkr_unwanted_string ^ set "bulkr_unwanted_string=" :: New string to replace the old one with. if not defined bulkr_new_string ^ set "bulkr_new_string=" :: Oh Noes, I am unable to recall which fix is for what fix. :: Remember folks: :: String.txt ~> PrefixStringSuffix.txt :: :: Don't forget to pad with spaces, underscores, dashes, etc :: Example: :: String.txt ~> Prefix_String_Suffix.txt :: :: Enter the new Prefix, Example: [awesomesause]_ if not defined bulkr_new_prefix ^ set "bulkr_new_prefix=" :: Enter the new Suffix, Example: _[awesomesause] if not defined bulkr_new_suffix ^ set "bulkr_new_suffix=" :: If you have provided all desired information via variables or parameters and wish to bypass prompts. :: ANY VALUE makes this true. NO VALUE makes this false if not defined bulkr_bypass_all_prompts ^ set "bulkr_bypass_all_prompts=" ::::::::::::::::::::::::::::::::::::::: goto :eof :SCRIPT_VARS :: Script Variables ::::::::::::::::::: set "bulkr_auto_bypass_all_prompts=" rem :: Default: Not Set :: If set, will ALWAYS bypass all prompts set "bulkr_default_timeout_value=3" rem :: Default: 3 :: How long to wait before processing when all prompts are bypassed set "bulkr_allow_prompted_vars=true" rem :: Default: true :: Does not unset the vars assosiated to params. set "bulkr_rename_bin=move" rem :: Default: move :: Binary used to perform the rename, 'rename' is an alternative although its not functional at the moment set "bulkr_current_directory=%cd%" rem :: Default: %cd% :: Enter the bulkr_current_directory path(examples: %cd% or '.\' or '%~dp0' ) ::::::::::::::::::::::::::::::::::::::: goto :eof ::::::::::::::::::::::::::::::::::::::: :: :: ::::: Do Not Modify Below ::::: :: :: ::::::::::::::::::::::::::::::::::::::: :START_SCRIPT call :SCRIPT_VARS call :CLEAR_VARS call :encode_utf8 call :SCRIPT_VARS call :help_check %~1 if defined bulkr_shown_help_flag goto :eof call :HARDCODED_INPUT call :PARAM_INPUT %* call :func_reset_counters call :PROMPT_INPUT call :ERROR_CHECK_1 call :INITIALIZE call :RENAME_LOOP call :SUMMARY call :CLEANUP call :CLEAR_VARS goto :eof ::::::::::::::::::::::::::::::::::::::: :: Clearing Variables ::::::::::::::::: :: Clears all bulkr_ variables :: :: only param vars bypassed :: :: :: :: :CLEAR_VARS for /f "tokens=1 delims==" %%x in ('set bulkr_') do ( if defined bulkr_allow_prompted_vars ( echo %%~x | findstr /i "bulkr_dir_with_files_to_rename bulkr_unwanted_string bulkr_new_string bulkr_new_prefix bulkr_new_suffix" 2>nul 1>nul if !errorlevel! neq 0 ( set "%%~x=" ) ) else ( set "%%~x=" ) ) goto :eof ::::::::::::::::::::::::::::::::::::::: :PARAM_INPUT :: Parameters :::::::::::::::::::::::: :: All Quotes will be removed :: :: Wrap the parameters in quotes :: :: :: :: Example: :: %0 %1 %2 %3 %4 %5 %6 :: script "Folder" "UnWanted" "New Text" "Add Preffix" "Add Suffix" "No Prompts" :: bulk_rename.bat "%USERPROFILE%\Downloads\Videos" "[Divx]" "" "" "[JXE]" "Trick Preeze" :: :: if not "%~1" equ "" set "bulkr_dir_with_files_to_rename=%~1" rem :: First Param = location where you'd like to rename the files. if not "%~2" equ "" set "bulkr_unwanted_string=%~2" rem :: Second Param = the string that you would like replaced. if not "%~3" equ "" set "bulkr_new_string=%~3" rem :: Third Param = new string to replace the old one with. if not "%~4" equ "" set "bulkr_new_prefix=%~4" rem :: Fourth Param = new Prefix, Example: [awesomesause]_ if not "%~5" equ "" set "bulkr_new_suffix=%~5" rem :: Fifth Param = new Suffix, Example: _[awesomesause] if not "%~6" equ "" set "bulkr_bypass_all_prompts=%~6" rem :: Sixth Param = Prompted input? I don't even know her. goto :eof ::::::::::::::::::::::::::::::::::::::: :PROMPT_INPUT :: Prompted Variables ::::::::::::::::: :: Will Only be prompted :: :: if they're not already set :: :: :: :: rem Superceeded Bypass support if defined bulkr_auto_bypass_all_prompts ( set "bulkr_bypass_all_prompts=%bulkr_auto_bypass_all_prompts%" ) rem Bypass support if defined bulkr_bypass_all_prompts ( echo INFO: Prompts bypassed call :func_set_file_totals call :DUMP_PARAMETERS ) else ( rem Prompting for any unset variables if not defined bulkr_dir_with_files_to_rename ( echo/ echo PROMPT: Enter the location where you'd like to rename the files: echo If left blank, defaults to [%bulkr_current_directory%] set /p "bulkr_dir_with_files_to_rename=>" ) call :func_set_file_totals call :func_set_sample_files if defined bulkr_sample_file1 ( echo/ Info: Cherry-Picked sample files for Copy-Paste ease for /l %%a in (1,1,5) do ( if defined bulkr_sample_file%%a echo/ !bulkr_sample_file%%a! ) ) if not defined bulkr_unwanted_string ( echo/ echo PROMPT: Enter the string that you would like replaced: set /p "bulkr_unwanted_string=>" ) if not defined bulkr_new_string ( echo/ echo PROMPT: Enter the new string to replace the old one with: set /p "bulkr_new_string=>" ) if not defined bulkr_new_prefix ( echo/ echo PROMPT: Enter the new Prefix, Example [or leave blank for none]: set /p "bulkr_new_prefix=>" ) if not defined bulkr_new_suffix ( echo/ echo PROMPT: Enter the new Suffix, Example [or leave blank for none]: set /p "bulkr_new_suffix=>" ) echo/ echo ------------------------------------------------------- ) goto :eof ::::::::::::::::::::::::::::::::::::::: :ERROR_CHECK_1 :: Basic Error Checking ::::::::::::::: if not defined bulkr_dir_with_files_to_rename ( if defined bulkr_current_directory ( set "bulkr_dir_with_files_to_rename=%bulkr_current_directory%" ) else ( set "bulkr_dir_with_files_to_rename=.\" ) ) rem Default Pause Timer Value if not defined bulkr_default_timeout_value ( set "bulkr_default_timeout_value=5" ) rem [bulkr_dir_with_files_to_rename] Cannot be empty if not defined bulkr_dir_with_files_to_rename ( echo Error: Fatal: Check-Variable: [^%bulkr_dir_with_files_to_rename^% is empty] Exiting... goto :eof ) goto :eof ::::::::::::::::::::::::::::::::::::::: rem Scrubbing Var Counts rem for /f "tokens=1 delims==" %%a in ('set bulkr_count_file_') do set "%%a=0" :INITIALIZE rem pushd to the dir to read attribs if exist "!bulkr_dir_with_files_to_rename!" ( pushd "!bulkr_dir_with_files_to_rename!" set /a "pushme_bulkr+=1" ) rem Normal totals - Calc string length for prepadded zeros-- Using str length to "UnLazy" the "Lazy Zeroes" if defined bulkr_count_file_total ( if !bulkr_count_file_total! geq 10 ( set "bulkr_Pvar=!bulkr_count_file_total!#" set "bulkr_padz_total=0" for %%P in (4096 2048 1024 512 256 128 64 32 16 8 4 2 1) do ( if "!bulkr_Pvar:~%%P,1!" NEQ "" ( set /a "bulkr_padz_total+=%%P" set "bulkr_Pvar=!bulkr_Pvar:~%%P!" ) ) ) ) rem Normal totals - Creating a working set of prepadded zeros from total -- deemed "Almost Lazy Zeros" if defined bulkr_padz_total ( for /l %%a in (1,1,!bulkr_padz_total!) do ( set "bulkr_padz=0!bulkr_padz!" ) ) else ( set "bulkr_padz=" ) goto :eof ::::::::::::::::::::::::::::::::::::::: :: rem Hidden totals - Calc string length for prepadded zeros-- Using str length to "UnLazy" the "Lazy Zeroes" :: if defined bulkr_count_file_hidden_total ( :: if !bulkr_count_file_hidden_total! geq 10 ( :: set "bulkr_Pvar=!bulkr_count_file_hidden_total!#" :: set "bulkr_hpadz_total=0" :: :: for %%P in (4096 2048 1024 512 256 128 64 32 16 8 4 2 1) do ( :: if "!bulkr_Pvar:~%%P,1!" NEQ "" ( :: set /a "bulkr_hpadz_total+=%%P" :: set "bulkr_Pvar=!bulkr_Pvar:~%%P!" :: ) :: ) :: ) :: ) :: :: rem Hidden totals - Creating a working set of prepadded zeros from total -- deemed "Almost Lazy Zeros" :: if defined bulkr_hpadz_total ( :: for /l %%a in (1,1,!bulkr_padz_total!) do ( :: set "bulkr_hpadz=0!bulkr_padz!" :: ) :: ) else ( :: set "bulkr_hpadz=" :: ) :: :: Renaming and erroring checking ::::: :: Allowing only Script Msgs :: :: All other outpout suppressed :: rem working string :: set "bulkr_fname_new=%bulkr_new_prefix%!bulkr_fname_only:%bulkr_unwanted_string%=%bulkr_new_string%!%bulkr_new_suffix%!bulkr_fname_extention!" rem Expansion attributes rem d ~0,1 rem - ~1,1 rem a ~2,1 rem h ~3,1 rem if wildcard is found process as wildcard - cmd limitations... rem this command is the key. Needs to be in a onliner. call echo %string:%string:*[=[%=% :RENAME_LOOP for /f "tokens=1* delims=" %%A in ('dir /b /o:-n /a:-d "!bulkr_dir_with_files_to_rename!"') do ( set "bulkr_fname_only=%%~nA" set "bulkr_fname_attrib=%%~aA" (set "bulkr_fname_new=!bulkr_new_prefix!!bulkr_fname_only:%bulkr_unwanted_string%=%bulkr_new_string%!!bulkr_new_suffix!%%~xA") rem Making sure Replacement strings are removed if not defined if not defined bulkr_unwanted_string ( if not defined bulkr_new_string ( set "bulkr_fname_new=%bulkr_new_prefix%!bulkr_fname_only!!bulkr_new_suffix!%%~xA" ) ) if "[%%~nxA]" equ "[!bulkr_fname_new!]" ( set /a "bulkr_count_file_same+=1" set /a "bulkr_count_file_current+=1" if defined bulkr_padz ( rem Pre-pad value with zeros and strip un-needed extras set "bulkr_pz_cntr=!bulkr_padz!!bulkr_count_file_current!" set "bulkr_pz_cntr=!bulkr_pz_cntr:~-%bulkr_padz_total%!" echo Info: SameName [!bulkr_pz_cntr!/%bulkr_count_file_total%]: [!bulkr_fname_new!] - [Same] ) else ( echo Info: SameName [!bulkr_count_file_current!/%bulkr_count_file_total%]: [!bulkr_fname_new!] - [Same] ) ) else ( rem unhide hidden files if /i "!bulkr_fname_attrib:~3,1!" equ "h" ( REM echo Info: Unhiding Hidden File: [%%~nxA] 2>nul 1>nul attrib -H "%%~nxA" if !errorlevel! equ 0 ( set /a "bulkr_count_file_nhidden+=1" set "hiddenfile_bulkr!bulkr_count_file_nhidden!=%%~nxA" ) ) rem Making sure the old filename exists if exist "%%~nxA" ( set /a "bulkr_count_file_current+=1" rem Making sure that the new filename does not exist if not exist "!bulkr_fname_new!" ( rem Moves OLD fname to NEW fname call %bulkr_rename_bin% "%%~nxA" "!bulkr_fname_new!" 2>nul 1>nul rem Making sure that the new filename was created if exist "!bulkr_fname_new!" ( if defined bulkr_padz ( rem Pre-pad value with zeros and strip un-needed extras set "bulkr_pz_cntr=!bulkr_padz!!bulkr_count_file_current!" set "bulkr_pz_cntr=!bulkr_pz_cntr:~-%bulkr_padz_total%!" echo Info: Success [!bulkr_pz_cntr!/%bulkr_count_file_total%]: [!bulkr_fname_new!] ) else ( echo Info: Success [!bulkr_count_file_current!/%bulkr_count_file_total%]: [!bulkr_fname_new!] ) ) else ( echo/ set /a "bulkr_count_file_error+=1" echo Error: Unable to find new filename - Path:[!bulkr_dir_with_files_to_rename!] File:[!bulkr_fname_new!] ) ) else ( echo/ set /a "bulkr_count_file_error+=1" echo Error: Destination File already exists ["!bulkr_fname_new!"] ) ) else ( echo/ set /a "bulkr_count_file_error+=1" echo Error: Internal Error. Unable to locate ["%%~nxA"] ) if defined hiddenfile_bulkr!bulkr_count_file_nhidden! ( 2>nul 1>nul attrib +H "!bulkr_fname_new!" if !errorlevel! equ 0 ( set "hiddenfile_bulkr!bulkr_count_file_nhidden!=" ) else ( echo/ set /a "bulkr_count_file_error+=1" echo Error: Internal Error. Unable to hide [attrib +H "!bulkr_fname_new!"] ) ) ) ) goto :eof ::::::::::::::::::::::::::::::::::::::: :SUMMARY :: Print Summary :::::::::::::::::::::: echo. echo ------------------------------------------------------- call :DUMP_PARAMETERS echo ------------------------------------------------------- echo. if !bulkr_count_file_error! gtr 0 ( echo Warning: Errors Found [%bulkr_count_file_error%] ) echo SUMMARY: Found:[!bulkr_count_file_total!] Same:[!bulkr_count_file_same!] Processed:[!bulkr_count_file_current!] Hidden:[!bulkr_count_file_nhidden!] Errors:[!bulkr_count_file_error!] goto :eof ::::::::::::::::::::::::::::::::::::::: :CLEANUP :: popd out of the pushd :::::::::::::: if defined pushme_bulkr ( for /l %%P in (1,1,!pushme_bulkr!) do ( popd "!bulkr_dir_with_files_to_rename!" ) ) else ( popd "!bulkr_dir_with_files_to_rename!" ) ::::::::::::::::::::::::::::::::::::::: :: Changing typeset back to original :: call :encode_orig goto :eof ::::::::::::::::::::::::::::::::::::::: :DUMP_PARAMETERS :: Display User prompted variables :::: echo/INFO: Dumping all set parameters: echo/ Directory :[!bulkr_dir_with_files_to_rename!] echo/ UnWanted Text :[%bulkr_unwanted_string%] echo/ Replace Text :[%bulkr_new_string%] echo/ Add Prefix :[%bulkr_new_prefix%] echo/ Add Suffix :[%bulkr_new_suffix%] goto :eof ::::::::::::::::::::::::::::::::::::::: ::::::::::::::::::::::::::::::::::::::: :: :: :: Changing typeset to utf8 :: :: because we love everyone :: :: that's utf8 supported :: :: T.T, Everyone else :: :: :: ::::::::::::::::::::::::::::::::::::::: :: Storing the original value :: If not utf8, making it so :encode_utf8 if not defined bulkr_orig_chcp call :set_bulkr_orig_chcp if !bulkr_orig_chcp! neq 437 ( chcp 437 if !errorlevel! neq 0 ( echo Error: Not Fatal: Unable to set UTF8 typeset... ) ) 2>nul 1>nul goto :eof ::::::::::::::::::::::::::::::::::::::: :set_bulkr_orig_chcp if not defined bulkr_orig_chcp ( for /f "tokens=4 delims=: " %%a in ('chcp') do set "bulkr_orig_chcp=%%a" ) goto :eof ::::::::::::::::::::::::::::::::::::::: :: If not orig, mskinh it so :: if orig is not set, changing to oem (us default) :: OneLiner - remind future self: Seemed like a good idea at the time :encode_orig if not defined bulkr_orig_chcp goto :eof for /f "tokens=4 delims=: " %%a in ('chcp') do ( if not %%~a geq 0 ( set "bulkr_current_chcp=" goto :eof ) else ( set "bulkr_current_chcp=%%a" ) ) if !bulkr_current_chcp! neq !bulkr_orig_chcp! ( chcp !bulkr_orig_chcp! 2>nul 1>nul if !errorlevel! neq 0 ( echo Error: Not Fatal: Unable to set !bulkr_orig_chcp! typeset... chcp 65001 if !errorlevel! neq 0 ( echo Error: Not Fatal: Unable to set 65001 typeset... ) ) ) goto :eof ::::::::::::::::::::::::::::::::::::::: rem unused atm -- bulkr_count_file_hidden_total rem Scrubbing Var Counts -- sets all counts to zero :func_reset_counters for %%v in ( bulkr_count_file_nhidden bulkr_count_file_current bulkr_count_file_total bulkr_count_file_error bulkr_count_file_same ) do ( set "%%v=0" ) goto :eof REM for /f "tokens=1* delims=" %%A in ('dir /b /o:-n /a:h /a:-d "!bulkr_dir_with_files_to_rename!" 2^>nul') do ( REM set /a "bulkr_count_file_hidden_total+=1" REM ) rem Getting total number of hidden files rem Getting total number of normal files :func_set_file_totals for /f "tokens=1* delims=" %%A in ('dir /b /o:-n /a:-d "!bulkr_dir_with_files_to_rename!"') do ( set /a "bulkr_count_file_total+=1" ) goto :eof rem Getting Sample file name set for easy copy-pasta :func_set_sample_files if not defined bulkr_count_file_total goto :eof set /a "bulkr_s1=(!bulkr_count_file_total! / 6)" for /l %%a in (2,1,5) do ( set /a "bulkr_s%%a=!bulkr_s1! * %%a" ) set "bulkr_cntr=0" if !bulkr_count_file_total! geq 6 ( for /f "tokens=1* delims=" %%A in ('dir /b /o:-n /a:-d "!bulkr_dir_with_files_to_rename!"') do ( set /a "bulkr_cntr+=1" if !bulkr_s1! equ !bulkr_cntr! ( set "bulkr_sample_file1=%%~nxA" ) else if !bulkr_s2! equ !bulkr_cntr! ( set "bulkr_sample_file2=%%~nxA" ) else if !bulkr_s3! equ !bulkr_cntr! ( set "bulkr_sample_file3=%%~nxA" ) else if !bulkr_s4! equ !bulkr_cntr! ( set "bulkr_sample_file4=%%~nxA" ) else if !bulkr_s5! equ !bulkr_cntr! ( set "bulkr_sample_file5=%%~nxA" ) ) ) 2>nul else ( for /f "tokens=1* delims=" %%A in ('dir /b /o:-n /a:-d "!bulkr_dir_with_files_to_rename!" 2^>nul') do ( set /a "bulkr_cntr+=1" set "bulkr_sample_file!bulkr_cntr!=%%~nA" ) ) set "bulkr_cntr=" goto :eof :: Calling For User Input ::::::::::::: :: Ignored if: :: :: "bulkr_bypass_all_prompts=1" :: :: Present Hardcoded Values :: :: Passed Parameters :: :: :: :: Checking for the help parameter :: :: Dumping Help Menu If needed :: :: :help_check if "%~1" equ "" goto :eof if /i "%~1" equ "/h" ( call :helpMe else if /i "%~1" equ "/help" ( call :helpMe else if /i "%~1" equ "-h" ( call :helpMe else if /i "%~1" equ "-help" ( call :helpMe else if ["%~1"] equ ["/?"] ( call :helpMe else if ["%~1"] equ ["-?"] ( call :helpMe ) echo/ goto :eof ::::::::::::::::::::::::::::::::::::::: :helpMe :: Help Menu :::::::::::::::::::::::::: set "bulkr_shown_help_flag=true" echo/ echo USAGE: bulk_rename.bat ["Folder" "UnWanted" "New Text" "Add Preffix" "Add Suffix" "No Prompts"] echo bulk_rename.bat [/^?^|/h^|-h^|-^?] for help echo/ echo {^*} Add/Remove/Replace Bulk file names. Directories not supported at this point echo/ echo {^*} Mix and Match Four Input Meathods echo In weighted order from TOP to BOTTOM, where top superceeds/overwrites bottom: echo - Parameters: Pass Parameters when calling script; overwrites all below echo - Hardcoded: Bake defaults into the script; overwrites all below echo - Predefined: Predefined variables in the shell; overwrites below echo - Prompted: Prompts user for input, unless bypassed echo/ echo/ echo {^*} Parameter Input Meathod: echo - First Param = location where you'd like to rename the file(s). echo - Second Param = the string that you would like replaced. echo - Third Param = New string to replace the old one with. echo - Fourth Param = new Prefix, Example: [awesomesause]_ echo - Fifth Param = new Suffix, Example: _[awesomesause] echo - Sixth Param = Prompted input? I don't even know her. echo/ echo {^*} Usage Example: Remove [Divx] tag; Append Suffix " [JXE]" and bypass all prompts echo - bulk_rename.bat "^%USERPROFILE^%\Downloads\Videos" "[Divx]" "" "" " [JXE]" "Trick Preeze" echo/ echo {^*} Usage Example: Replace all Double Spaces with Single Spaces and bypass all prompts echo - bulk_rename.bat "^%USERPROFILE^%\Downloads\Videos" " " " " "" "" "Trick Preeze" echo/ echo {^*} Usage Example: Prompt for all fields echo - bulk_rename.bat echo/ echo {^*} Parameter Input Meathod: echo - Batch/cmd - Use (please note the quotes): set "[variable below]=[value]" echo # bulkr_dir_with_files_to_rename echo # bulkr_unwanted_string echo # bulkr_new_string echo # bulkr_new_prefix echo # bulkr_new_suffix echo # bulkr_bypass_all_prompts echo/ goto :eof ::::::::::::::::::::::::::::::::::::::: ::::::::::::::::::::::::::::::::::::::: :: :: ---------------------------------------- :: Thanks, Sources, and/or [Sourced-]Contributions :: ---------------------------------------- :: + Feature: Prepadded Zeros :: ~> Credited Author: jeb - https://stackoverflow.com/users/463115/jeb :: * Determine string length -- https://stackoverflow.com/a/19101275 :: * "Lazy Zeros" -- https://stackoverflow.com/a/9430912 :: ---------------------------------------- :: :: :: ---------------------------------------- :: Version History :: ---------------------------------------- :: * 09/12/2016: #Fixed Param Process order; #Added More info in 'help'; #Fixed Possible issue of blank params overwriting all other input methods :: * 07/12/2017: #Added bulkr_ prefix to all params to unset all vars easily; #Added setting to allow param pre-sets so certain vars are not cleared :: * 07/23/2017: #Changed default var [bulkr_current_directory] to %cd%; #Fixed Issue where script vars were being cleared #Added Padded current count. :: * 08/02/2017: #Fixed the weird bug when files contained certain special characters; #Rewrote chcp functions and changed folder detection to increase script speed. :: ---------------------------------------- :: :: :: ---------------------------------------- :: Blah Blah Blah -- Notes -- Bleh *hic* :: ---------------------------------------- :: @ 07/23/2017 ~ I finally admit it, this code is ugly :: After modifying this script these past couple of weeks, it seemed that there were too many useless blocks :: And trying to follow the execution order was a confusing mess. :: I've come to the conclusion that this script will need to be completely rewritten. :: Focus would be on: :: - Expanding the feature set - rename dirs, recurse via tree, hidden/system/special files, etc :: - Nothing too M$Crazy, but keeping "unix-style apps" in mind :: - Args parse pl9x :: - Faster - (I'm no expert, so bare with me) :: - Overall Structure Flow - (I won't dare say "better"/"improved"/etc) :: :::::::::::::::::::::::::::::::::::::::