Пакетное: переименовать все файлы и подпапки - PullRequest
0 голосов
/ 11 ноября 2011
for /f "tokens=*" %%f in ('dir /ad /s /b "C:\Users\Tin\Desktop\renameFolders"') do (
setlocal enabledelayedexpansion enableextensions
  set N=%%f
  set N=!N: =_!
  ren "%%f" "!N!"
)

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

Структура файла: тест:

file 2.txt
file 1.txt
folder 1
test.bat

папка 1:

folder 2
file 3.txt

папка 2: файл 4.txt

Ответы [ 2 ]

2 голосов
/ 12 ноября 2011

Проблема здесь в том, что ЗАКАЗАТЬ, в котором необходимо сделать переименование папок. Самая глубокая папка должна быть сначала переименована, и процесс переименования должен продолжаться вверх, пока не достигнет папки верхнего уровня. Единственный способ сделать это через рекурсивную подпрограмму, которая обрабатывает каждую существующую папку следующим образом:

Rename the files in this folder.
For each folder in this folder:
    Process it recursively.
    Rename it.

Также обратите внимание, что не все файлы / папки должны быть переименованы, а только те, в имени которых есть пробелы; в противном случае команда REN выдаст ошибку. Пакетный файл ниже принимает в качестве первого аргумента папку верхнего уровня для обработки:

@echo off
setlocal EnableDelayedExpansion EnableExtensions
pushd %1
call :ProcessThisFolder
popd
exit /b

:ProcessThisFolder
REM Rename the files in this folder.
for %%f in (*.*) do (
    set "old=%%f"
    set new=!old: =_!
    if not !new! == !old! ren "!old!" "!new!"
)
REM For each folder in this folder:
for /D %%d in (*) do (
    REM Process it recursively.
    cd %%d
    call :ProcessThisFolder
    cd ..
    REM Rename it.
    set "old=%%d"
    set new=!old: =_!
    if not !new! == !old! ren "!old!" "!new!"
)

EDIT

Проблема с оригинальным методом - порядок, в котором будут выполняться переименования. Предположим, что результат dir /s /b ...:

C:\Users\Tin\Desktop\renameFolders\file 1.txt
C:\Users\Tin\Desktop\renameFolders\file 2.txt
C:\Users\Tin\Desktop\renameFolders\folder 1
C:\Users\Tin\Desktop\renameFolders\folder 1\file 3.txt
C:\Users\Tin\Desktop\renameFolders\folder 1\folder 2

Когда строка 3 обрабатывается, folder 1 переименовывается в folder_1, поэтому на этом этапе имена в строках 4 и 5 больше не действительны. Первое переименование необходимо выполнить для file 3.txt и folder 2, а затем перейти вверх к указанным выше папкам, но строки, отображаемые командой dir, отсортированы в алфавитном порядке, и другие доступные порядки в этом случае не помогают.

Первая часть вышеприведенной программы работает следующим образом:

pushd %1                 Save current directory and do a CD %1
call :ProcessThisFolder  Call the subroutine defined in this same file below
popd                     Do a CD to the directory saved by previous PUSHD
exit /b                  Terminate here this Batch file; otherwise the lines
. . .                    below would be executed again

Вы можете просмотреть действие любой команды, выполнив ее с помощью /? параметр, например: pushd /?.

2 голосов
/ 11 ноября 2011

С моей точки зрения, у вас есть три проблемы:

  1. Использование параметра / ad означает, что вы будете обрабатывать только каталоги, а не файлы
  2. set N=%%f приведет к тому, что N получит полное имя, включая путь, поскольку dir /b возвращает
  3. Рекурсия должна быть обратной. Если вы переименуете «папка 1» в «папка_1», то при проверке «папка 1 / папка 2» путь больше не будет действительным.

Исправление (1) просто удаляет /ad Исправление (2) используется set N=%%~nxf Я еще не уверен, как исправить # 3. Я случайно обнаружил, что при повторном запуске сценария с исправленными (1) и (2) все файлы будут переименованы. Но я уверен, что есть лучший ответ.

...