简体   繁体   中英

How to replace all spaces by underscores in all file and folder names recursively in a directory tree?

There is How to replace all spaces by underscores in all file names of a folder?
It contains solutions to rename all files in a folder with one or more spaces in file name by replacing the spaces by underscores.

How do I recursively rename the whole path including every directory name of that file rather than only the file name itself?

For example the current directory is C:\\example and it contains:

C:\example\some stupid file path with whitespace\my file.exe
C:\example\another stupid whitespaced dir\another file.exe

The folders and files should be renamed to:

C:\example\some_stupid_file_path_with_whitespace\my_file.exe
C:\example\another_stupid_whitespaced_dir\another_file.exe

How can this recursive file and folder renames be done?

Here is a batch code for this task:

@echo off
setlocal EnableExtensions DisableDelayedExpansion
set "StartFolder=C:\example"

rem Get the absolute path of the path of the start folder.
for %%I in ("%StartFolder%") do set "StartFolder=%%~fI"
rem Get the length of the absolute path of the start folder.
setlocal EnableDelayedExpansion
set "FolderPath=A!StartFolder!
set "StartPathLength=0"
for /L %%I in (12,-1,0) do set /A "StartPathLength|=1<<%%I" & for %%J in (!StartPathLength!) do if "!FolderPath:~%%J,1!"=="" set /A "StartPathLength&=~1<<%%I"
endlocal & set "StartPathLength=%StartPathLength%"

cd /D %SystemRoot%
set "RenameError="

rem Rename all files containing at least one space character in file name.
for /F "delims=" %%I in ('dir "%StartFolder%\* *" /A-D /B /S 2^>nul') do call :RenameFile "%%I"

rem Rename all folders containing at least one space character in folder name.
for /F "delims=" %%I in ('dir "%StartFolder%\* *" /AD /B /S 2^>nul') do call :RenameFolder "%%I"

if defined RenameError echo/& pause
rem Restore initial environment and exit this batch file.
endlocal
goto :EOF


:RenameFile
set "NewFileName=%~nx1"
set "NewFileName=%NewFileName: =_%"

set "FileAttributes=%~a1"
if "%FileAttributes:~3,1%" == "h" %SystemRoot%\System32\attrib.exe -h %1

ren %1 "%NewFileName%" 2>nul
if errorlevel 1 goto ErrorFileRename

if "%FileAttributes:~3,1%" == "h" %SystemRoot%\System32\attrib.exe +h "%~dp1%NewFileName%"
goto :EOF

:ErrorFileRename
echo Error renaming file %1
set "RenameError=1"
if "%FileAttributes:~3,1%" == "h" %SystemRoot%\System32\attrib.exe +h %1
goto :EOF


:RenameFolder
set "NewFolderName=%~nx1"
set "NewFolderName=%NewFolderName: =_%"

set "FolderPath=%~dp1"
setlocal EnableDelayedExpansion
set "FolderPath=!FolderPath:~12!"
endlocal & set "FolderPath=%FolderPath%"
if not exist "%StartFolder%%FolderPath%" set "FolderPath=%FolderPath: =_%"
set "FullFolderName=%StartFolder%%FolderPath%%~nx1"
if not exist "%FullFolderName%\" echo Error finding folder "%FullFolderName%"& set "RenameError=1" & goto :EOF

for %%J in ("%FullFolderName%") do set "FolderAttributes=%%~aJ"
if "%FolderAttributes:~3,1%" == "h" %SystemRoot%\System32\attrib.exe -h "%FullFolderName%"

ren "%FullFolderName%" "%NewFolderName%" 2>nul
if errorlevel 1 goto ErrorFolderRename

if "%FolderAttributes:~3,1%" == "h" %SystemRoot%\System32\attrib.exe +h "%FolderPath%%NewFolderName%"
goto :EOF

:ErrorFolderRename
echo Error renaming folder "%FullFolderName%"
set "RenameError=1"
if "%FolderAttributes:~3,1%" == "h" %SystemRoot%\System32\attrib.exe +h "%FullFolderName%"
goto :EOF

It works also for hidden files and folders and for files and folders containing an exclamation mark in full qualified file/folder name.

The batch file outputs an error message if renaming a file or folder failed because of following reasons:

  1. An existing file/folder in same folder has already the new file/folder name.
  2. The used user account does not have the required permissions to rename the file/folder.
  3. The folder to rename is the current directory of any running process.
  4. The file to rename is opened by a running process with file access permissions set by the process preventing renaming the opened file.
  5. A file in folder to rename or one of its subfolders is opened by a running process with file access permissions set by the process preventing renaming or deletion of the file which results also in preventing renaming or deletion of any folder in path of this opened file.
  6. A file or folder to rename cannot be found anymore because of being deleted while the batch file processes the entire folder tree.

The batch file pause at end if any file/folder renaming error occurred so that a user double clicking on the batch file can read the error messages. There is no pause if no renaming error occurred during execution.

The batch file does not try to rename as much folders with a space in name as possible. So if for example a folder on level 2 with at least one space in name could not be renamed, all subfolders with a space in name on level 4 and below are also not renamed. The batch file contains only code to handle the situation that none of the folders in path containing one or more spaces to current folder could be renamed before. In this case it tries to rename nevertheless the current subfolder with space in folder name.

The batch file sets current directory for the running command process temporarily to Windows directory to make sure that the current command process does not prevent renaming of folder in folder tree.

The batch file should not contain a space in file name and should not be in one of the subfolders of the folder assigned to environment variable StartFolder . There is no code added to verify those two requirements before starting the file/folder renaming procedure.

For understanding the used commands and how they work, open a command prompt window, execute there the following commands, and read entirely all help pages displayed for each command very carefully.

  • attrib /?
  • call /?
  • dir /?
  • echo /?
  • endlocal /?
  • for /?
  • goto /?
  • if /?
  • pause /?
  • ren /?
  • set /?
  • setlocal /?

See also:

The redirection operator > must be escaped with caret character ^ on both FOR command lines to be interpreted as literal character when Windows command interpreter processes this command line before executing command FOR which executes the embedded dir command line in a separate command process started in background with cmd.exe /C .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM