windows - 如何在目录树中递归地用下划线替换所有文件和文件夹名称中的所有空格?

标签 windows batch-file cmd directory rename

How to replace all spaces by underscores in all file names of a folder?
它包含通过用下划线替换空格来重命名文件夹中文件名中包含一个或多个空格的所有文件的解决方案。

如何递归地重命名整个路径,包括该文件的每个目录名,而不仅仅是文件名本身?

例如,当前目录是C:\example,它包含:

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

文件夹和文件应重命名为:

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

如何完成这种递归文件和文件夹重命名?

最佳答案

这是此任务的批处理代码:

@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

它也适用于隐藏文件和文件夹以及完全限定文件/文件夹名称中包含感叹号的文件和文件夹。

如果由于以下原因重命名文件或文件夹失败,批处理文件会输出错误消息:

  1. 同一文件夹中的现有文件/文件夹已具有新的文件/文件夹名称。
  2. 所使用的用户帐户没有重命名文件/文件夹所需的权限。
  3. 要重命名的文件夹是任何正在运行的进程的当前目录。
  4. 要重命名的文件由正在运行的进程打开,该进程设置了文件访问权限,以防止重命名打开的文件。
  5. 要重命名的文件夹或其子文件夹之一由正在运行的进程打开,该进程设置的文件访问权限阻止重命名或删除该文件,这也会导致阻止重命名或删除该路径中的任何文件夹打开的文件。
  6. 由于在批处理文件处理整个文件夹树时被删除,因此无法再找到要重命名的文件或文件夹。

如果发生任何文件/文件夹重命名错误,批处理文件会在末尾暂停,以便用户双击批处理文件可以读取错误消息。如果执行过程中没有发生重命名错误,则不会暂停。

批处理文件不会尝试重命名尽可能多的名称中带有空格的文件夹。因此,如果无法重命名第 2 层名称中至少有一个空格的文件夹,则第 4 层及以下名称中包含空格的所有子文件夹也不会被重命名。该批处理文件仅包含用于处理以下情况的代码:当前文件夹中包含一个或多个空格的路径中的任何文件夹都不能被重命名。在这种情况下,它会尝试使用文件夹名称中的空格来重命名当前子文件夹。

批处理文件将运行命令进程的当前目录临时设置为Windows目录,以确保当前命令进程不会阻止文件夹树中文件夹的重命名。

批处理文件的文件名中不应包含空格,也不应位于分配给环境变量 StartFolder 的文件夹的子文件夹之一中。在开始文件/文件夹重命名过程之前,没有添加任何代码来验证这两个要求。

为了了解所使用的命令及其工作原理,请打开命令提示符窗口,执行以下命令,并仔细阅读每个命令显示的所有帮助页面。

  • attrib/?
  • 调用/?
  • 目录/?
  • 回显/?
  • endlocal/?
  • 对于/?
  • 转到/?
  • 如果/?
  • 暂停/?
  • 任/?
  • 设置/?
  • setlocal/?

另请参阅:

重定向运算符 > 必须在两个 FOR 命令行上使用脱字符号 ^ 进行转义,以便在 Windows 命令解释器时将其解释为文字字符在执行命令 FOR 之前处理此命令行,命令使用 cmd.exe/C 在后台启动的单独命令进程执行嵌入的 dir 命令行>.

关于windows - 如何在目录树中递归地用下划线替换所有文件和文件夹名称中的所有空格?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52067917/

相关文章:

c++ - 当 stderr 重定向到管道时,为什么 boost::process 在 Windows 上崩溃?

postgresql - 为什么 pg_restore 返回 "options -d/--dbname and -f/--file cannot be used together"?

windows - 循环遍历 .bat 中的行并存储变量而不覆盖

java - 如何从 CMD 编译并运行依赖于 JAR 文件的 java 文件?

java - Java 操作系统的不同图标大小

windows - 作为构建过程的一部分,如何在 Windows 机器上远程执行命令?

java - 如果在 Windows Server 2016 上以非管理员身份运行,exit/b 0 在 process.exitValue 中返回 1

命令提示符中可以识别 Java,但我无法安装任何需要 Java 的程序?

c# - 想隐藏cmd提示画面

c - 在 C 中读取 Unicode 文件并通过套接字将内容作为 ASCII 传递