Как заменить все пробелы символами подчеркивания во всех именах файлов и папок в дереве каталогов? - PullRequest
0 голосов
/ 29 августа 2018

Существует Как заменить все пробелы подчеркиванием во всех именах файлов в папке?
Он содержит решения для переименования всех файлов в папке с одним или несколькими пробелами в имени файла, заменив пробелы подчеркиванием.

Как мне рекурсивно переименовать весь путь, включая каждое имя каталога этого файла, а не только имя самого файла?

Например, текущий каталог 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

Как сделать это рекурсивное переименование файлов и папок?

1 Ответ

0 голосов
/ 29 августа 2018

Вот код пакета для этой задачи:

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

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"
if not exist "%FolderPath%" set "FolderPath=%FolderPath: =_%"
set "FullFolderName=%FolderPath%%~nx1"
if not exist "%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. Файл в папке для переименования или в одной из ее подпапок открывается запущенным процессом с правами доступа к файлу, установленными процессом, предотвращающим переименование или удаление файла, что также приводит к предотвращению переименования или удаления любой папки в пути к этому открытый файл.

Пауза пакетного файла в конце, если произошла какая-либо ошибка переименования файла / папки, чтобы пользователь дважды щелкнув по пакетному файлу, мог прочитать сообщения об ошибке. Пауза не возникает, если во время выполнения не произошла ошибка переименования.

Пакетный файл не пытается переименовать как можно больше папок с пробелом в имени. Так, если, например, папку на уровне 2 с хотя бы одним пробелом в имени не удалось переименовать, все подпапки с пробелом в имени на уровне 4 и ниже также не переименовываются. Пакетный файл содержит только код для обработки ситуации, когда ни одна из папок в пути, содержащих один или несколько пробелов в текущей папке, не могла быть переименована ранее. В этом случае он все же пытается переименовать текущую подпапку с пробелом в имени папки.

Пакетный файл временно устанавливает текущий каталог для запущенного командного процесса в каталог Windows, чтобы убедиться, что текущий командный процесс не препятствует переименованию папки в дереве папок.

Пакетный файл не должен содержать пробел в имени файла и не должен находиться в одной из подпапок папки, назначенной переменной среды StartFolder. Код не добавлен для проверки этих двух требований перед началом процедуры переименования файла / папки.

Чтобы понять используемые команды и то, как они работают, откройте окно командной строки, выполните там следующие команды и полностью прочитайте все страницы справки, отображаемые для каждой команды.

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

Смотри также:

Оператор перенаправления > должен быть экранирован с помощью символа вставки ^ в обеих командных строках FOR , чтобы интерпретироваться как литеральный символ, когда интерпретатор команд Windows обрабатывает эту командную строку перед выполнением команды FOR , который выполняет встроенную командную строку dir в отдельном командном процессе, запущенном в фоновом режиме с cmd.exe /C.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...