Пакетный файл для перемещения файлов на один уровень переименование дубликатов
Я пытался создать командный файл, который я мог бы просто вставить в директорию MAIN FOLDER, и при его запуске все *.EXT переместятся на один уровень вверх в Folder2 и Folder3 соответственно:
C:\Main Folder\Folder2\Folder3a\File1.EXT
C:\Main Folder\Folder2\Folder3b\File2.EXT
C:\Main Folder\Folder2\Folder3c\File3.EXT
C:\Main Folder\Folder2\Folder3d\File1.EXT
C:\Main Folder\Folder3\Folder3a\File1.EXT
C:\Main Folder\Folder3\Folder3b\File2.EXT
C:\Main Folder\Folder3\Folder3c\File3.EXT
C:\Main Folder\Folder3\Folder3d\File1.EXT
Проблема в том, что в подпапках Folder2 и Folder3 есть дубликаты: File1.EXT.
Все, что я нашел здесь для перемещения файлов на один уровень, всегда перезаписывает дубликаты.
И решения, которые я нашел для переименования дубликатов, не "слились" с решениями для перемещения файлов.
Кто-нибудь может предложить более простой способ?
2 ответа
Этот закомментированный пакетный файл может использоваться для этой задачи:
@echo off
setlocal EnableExtensions DisableDelayedExpansion
rem Search for any file two directory levels below specified directory
rem and pass to subroutine MoveFile the name of the file with full path.
for /D %%A in ("C:\Main Folder\*") do (
for /D %%B in ("%%A\*") do (
for /F "delims=" %%I in ('dir "%%B\*" /A-D /B /S 2^>nul') do call :MoveFile "%%I"
)
)
endlocal
goto :EOF
:MoveFile
set "FilePath=%~dp1"
set "FileNameOnly=%~n1"
set "FileNameFull=%~1"
set "FileName+Ext=%~nx1"
set "FileExtension=%~x1"
rem For files staring with a dot and not containing one more dot.
if "%FileNameOnly%" == "" set "FileNameOnly=%~x1" & set "FileExtension="
rem Get path to parent folder ending with a backslash.
for /F "delims=" %%J in ("%FilePath:~0,-1%") do set "FileParent=%%~dpJ"
rem Uncomment the line below to see the values of the six File* variables.
rem set File & echo/
rem Does a file with current file name not exist in parent folder?
if not exist "%FileParent%%FileName+Ext%" (
rem Move the file to parent folder and if this was successful
rem delete the folder of the moved file if being empty now.
move "%FileNameFull%" "%FileParent%%FileName+Ext%" >nul
if not errorlevel 1 rd "%FilePath%" 2>nul
goto :EOF
)
set "FileNumber=1"
:NextFile
if exist "%FileParent%%FileNameOnly%_%FileNumber%%FileExtension%" set /A "FileNumber+=1" & goto NextFile
move "%FileNameFull%" "%FileParent%%FileNameOnly%_%FileNumber%%FileExtension%" >nul
if not errorlevel 1 rd "%FilePath%" 2>nul
goto :EOF
Результат для данного примера:
C:\Main Folder\Folder2\File1.EXT
C:\Main Folder\Folder2\File1_1.EXT
C:\Main Folder\Folder2\File2.EXT
C:\Main Folder\Folder2\File3.EXT
C:\Main Folder\Folder3\File1.EXT
C:\Main Folder\Folder3\File1_1.EXT
C:\Main Folder\Folder3\File2.EXT
C:\Main Folder\Folder3\File3.EXT
И второй запуск командного файла ничего не меняет.
Чтобы понять используемые команды и то, как они работают, откройте окно командной строки, выполните там следующие команды и полностью прочитайте все страницы справки, отображаемые для каждой команды.
call /?
echo /?
endlocal /?
for /?
goto /?
if /?
move /?
rd /?
rem /?
set /?
setlocal /?
Смотрите также:
@echo off
setlocal
if "%~1" == "test" call :test
for /d /r %%F in (*) do (
for /d %%G in ("%%F\*") do (
for %%H in ("%%~G\*.EXT") do (
call :move "%%~H" "%%~F"
)
)
)
exit /b
:move
setlocal
if /i not exist "%~2\%~nx1" (
echo 1. move "%~1" "%~2"
move "%~1" "%~2"
exit /b
)
set "name=%~n1"
for /l %%I in (1 1 9) do (
if "%name:~-4%" == " (%%I)" (
set "name=%name:~0,-4%"
)
)
for /l %%I in (1 1 9) do (
if not exist "%~2\%name% (%%I)%~x1" (
echo 2. move "%~1" "%~2\%name% (%%I)%~x1"
move "%~1" "%~2\%name% (%%I)%~x1"
exit /b
)
)
exit /b
:test
if exist "Main Folder" rd /s /q "Main Folder"
call :prep "Main Folder\Folder2\Folder3a" "File1.EXT"
call :prep "Main Folder\Folder2\Folder3b" "File2.EXT"
call :prep "Main Folder\Folder2\Folder3c" "File3.EXT"
call :prep "Main Folder\Folder2\Folder3d" "File1.EXT"
call :prep "Main Folder\Folder3\Folder3a" "File1.EXT"
call :prep "Main Folder\Folder3\Folder3b" "File2.EXT"
call :prep "Main Folder\Folder3\Folder3c" "File3.EXT"
call :prep "Main Folder\Folder3\Folder3d" "File1.EXT"
pushd "Main Folder" || exit /b 1
echo Prepared to test.
pause
exit /b
:prep
if /i not exist "%~1" md "%~1"
if /i not exist "%~1\%~2" type nul > "%~1\%~2"
exit /b
Интегрированный тестовый код облегчает тестирование. Удалите тестовый код, если хотите. Тест с использованием test
как 1-й аргумент т.е. main.cmd test
,
На основе цикла, который вы опубликовали в разделе Как создать пакетный файл, который перемещает файлы из подпапки на один уровень, переименовывая дубликаты? Цикл возвращает путь к целевому файлу и каталогу назначения.
Этикетка :move
вызывается с каждым циклом цикла и 1-й определяет, не существует ли файл назначения. Если не существует, выполняет перемещение и выходит из метки. Если существует, использует другой цикл для обнаружения и обрезает имя файла, если оно заканчивается (N)
где N
это число от 1 до 9. Затем он входит в другой цикл для перемещения с именем файла назначения с доступным 1-м (N)
добавлено к имени.
Проверено в корне D:\
, Я получаю вывод:
D:\> main.cmd test
Prepared to test.
Press any key to continue . . .
1. move "D:\Main Folder\Folder2\Folder3a\File1.EXT" "D:\Main Folder\Folder2"
1 file(s) moved.
1. move "D:\Main Folder\Folder2\Folder3b\File2.EXT" "D:\Main Folder\Folder2"
1 file(s) moved.
1. move "D:\Main Folder\Folder2\Folder3c\File3.EXT" "D:\Main Folder\Folder2"
1 file(s) moved.
2. move "D:\Main Folder\Folder2\Folder3d\File1.EXT" "D:\Main Folder\Folder2\File1 (1).EXT"
1 file(s) moved.
1. move "D:\Main Folder\Folder3\Folder3a\File1.EXT" "D:\Main Folder\Folder3"
1 file(s) moved.
1. move "D:\Main Folder\Folder3\Folder3b\File2.EXT" "D:\Main Folder\Folder3"
1 file(s) moved.
1. move "D:\Main Folder\Folder3\Folder3c\File3.EXT" "D:\Main Folder\Folder3"
1 file(s) moved.
2. move "D:\Main Folder\Folder3\Folder3d\File1.EXT" "D:\Main Folder\Folder3\File1 (1).EXT"
1 file(s) moved.
Как видно, 2 файла перемещены с (1)
добавляется к имени файла. Это строки, начинающиеся с 2.
, Линии, начинающиеся с 1.
переехали с неизмененными именами файлов.