Показать полную графическую версию : [решено] Автозамена при перемещении
У меня есть много одинаковых (по имени - Material3) папок в различных под папках, очень много, в эти папках находятся *.mat файлы, среди *.mat файлов попадаются одинаковые
скриптом:
for /f "tokens=*" %%b in ('dir /b /s Material3') do move /y "%%b" "%%~dpb../.."
перемещаю все эти папки в одно место, т.о. все папки должны слиться в одну, а все файлы *.mat переместиться в эту папку с заменой соответсвенно, но несмотря на использование ключа /y (пробовал и /Y) скрипт постоянно спрашивает о замене, как сделать автозамену в скрипте?
- ключ /Y работает только для файлов, а не для папок;
- в каталоге батника не должно быть папки "Material3", иначе DIR просто выдаст её содержимое;
вариант через XCOPY и RD:
if not exist Material3 for /f "delims=" %%a in ('dir /b/s/ad Material3') do (
xcopy /q/s/y/h/r "%%a\*" "%%~dpb..\..\Material3\" && rd /q/s "%%a"
)
дело в том, что общий объём файлов может составлять до 50 гб, поэтому и хотел использовать именно move, так как нет возможности копировать такое количество мегабайт
add:
ваш вариант работает
add2:
а как работает скрипт?
находит папку -> копирует в нужное место -> удаляет оригинал
так?
либо
находит папку -> копирует в нужное место -> находит папку -> копирует в нужное место -> ...находит и копирует все папки... -> удаляет оригиналы
так?
если первый вариант, то это вполне нормально (на диске единовременно не будет очень много скопированной информации)
как работает скрипт? »в цикле перебираются все папки, которые поочередно копируются и сразу удаляются
хотел использовать именно move »тогда только пофайлово:
@echo off
SETLOCAL EnableDelayedExpansion
for /f "delims=" %%d in ('dir /b/s/ad "Material3.*"') do if "%%~xd"=="" (
for /f "delims=" %%f in ('dir /b/s/a-d "%%d"') do (
set "$d=%%~dpf"& set "$d=!$d:%%~dpd=%%~dpd..\..\!"
if not exist "!$d!" md "!$d!"
if exist "!$d!" move "%%f" "!$d!"
))
- исходные папки после перемещения файлов не удаляются;
- операция одноразовая, скрипт поднимает на два уровня каждую папку Material3, 2-й запуск поднимет также и целевую папку, т.к. у них одинаковые имена
Большое спасибо, всё работает!
появилась проблема, иногда файлы в папках Material3 имеют одинаковое имя, но разный размер (т.е по сути это другие файлы), как сделать так чтобы перед заменой файлов проводилась проверка размера, и если файл *.mat в папке имеет то же имя, но другой размер то к имени нового файла добалялось бы "01,02,03...и.т.д"
Tosyk, как-то так:
@echo off
SETLOCAL EnableDelayedExpansion
for /f "delims=" %%d in ('dir/b/s/ad "Material3.*"') do if "%%~xd"=="" (
for /f "delims=" %%f in ('dir/b/s/a-d "%%d"') do (
set "$d=%%~dpf"& set "$d=!$d:%%~dpd=%%~dpd..\..\!"
call:MoveRen "%%f" "!$d!"
))
:MoveRen %source_file% %destin_folder%
::-------------------------------------
set "$s="& set "$n="& if "%~1"=="" GoTo:EOF
if not exist "%~2" md "%~2"||exit/b 1
:MoveRen_Loop
if not exist "%~2%~n1%$s%%~x1" move "%~1" "%~2%~n1%$s%%~x1"& GoTo:EOF
fc/b "%~1" "%~2%~n1%$s%%~x1">nul&&(del/f/q "%~1"& GoTo:EOF)
set/a "$n+=1"& set "$s=0!$n!"& set "$s=_!$s:~-2!"
GoTo:MoveRen_Loop
проверил, работает, проверяет, изменяет имя, по крайней мере первого уровня (_01.mat)
а как добавить ещё одну (или несколько) папку в обработку помимо Material3, пытаюсь сделать:
@echo off
SETLOCAL EnableDelayedExpansion
for /f "delims=" %%d in ('dir/b/s/ad "Material3.*"') do if "%%~xd"=="" (
for /f "delims=" %%f in ('dir/b/s/a-d "%%d"') do (
set "$d=%%~dpf"& set "$d=!$d:%%~dpd=%%~dpd..\..\!"
call:MoveRen "%%f" "!$d!"
))
:MoveRen %source_file% %destin_folder%
::-------------------------------------
set "$s="& set "$n="& if "%~1"=="" GoTo:EOF
if not exist "%~2" md "%~2"||exit/b 1
:MoveRen_Loop
if not exist "%~2%~n1%$s%%~x1" move "%~1" "%~2%~n1%$s%%~x1"& GoTo:EOF
fc/b "%~1" "%~2%~n1%$s%%~x1">nul&&(del/f/q "%~1"& GoTo:EOF)
set/a "$n+=1"& set "$s=0!$n!"& set "$s=_!$s:~-2!"
GoTo:MoveRen_Loop
for /f "delims=" %%d in ('dir/b/s/ad "MaterialConst.*"') do if "%%~xd"=="" (
for /f "delims=" %%f in ('dir/b/s/a-d "%%d"') do (
set "$d=%%~dpf"& set "$d=!$d:%%~dpd=%%~dpd..\..\!"
call:MoveRen "%%f" "!$d!"
))
:MoveRen %source_file% %destin_folder%
::-------------------------------------
set "$s="& set "$n="& if "%~1"=="" GoTo:EOF
if not exist "%~2" md "%~2"||exit/b 1
:MoveRen_Loop
if not exist "%~2%~n1%$s%%~x1" move "%~1" "%~2%~n1%$s%%~x1"& GoTo:EOF
fc/b "%~1" "%~2%~n1%$s%%~x1">nul&&(del/f/q "%~1"& GoTo:EOF)
set/a "$n+=1"& set "$s=0!$n!"& set "$s=_!$s:~-2!"
GoTo:MoveRen_Loop
но получается только Material3, остальные скрипт не трогает.
попробуйте программу robocopy . это типа xcopy и просто copy , так же она от Microsoft и имеет КУЧУ пользных и гибких ключей , для копирование и т.п.
попробуйте программу robocopy . это типа xcopy и просто copy , так же она от Microsoft и имеет КУЧУ пользных и гибких ключей , для копирование и т.п. »
спасибо, я посмотрел, но с cmd я уже хотя бы более менее разбираюсь, а robocopy для меня сложновато, не нашёл там нужных функция даже
а как добавить ещё одну (или несколько) папку в обработку »оформить как процедуру:
@echo off
SETLOCAL EnableDelayedExpansion
Call :MainExe Material3
Call :MainExe MaterialConst
EXIT
:MainExe %folder_name%
::---------------------
set "set $d="& if "%~1"=="" GoTo:EOF
for /f "delims=" %%d in ('dir/b/s/ad "%~1.*"') do if "%%~xd"=="" (
for /f "delims=" %%f in ('dir/b/s/a-d "%%d"') do (
set "$d=%%~dpf"& set "$d=!$d:%%~dpd=%%~dpd..\..\!"
call:MoveRen "%%f" "!$d!"
))
GoTo:EOF
:MoveRen %source_file% %destin_folder%
::-------------------------------------
set "$s="& set "$n="& if "%~1"=="" GoTo:EOF
if not exist "%~2" md "%~2"||exit/b 1
:MoveRen_Loop
if not exist "%~2%~n1%$s%%~x1" move "%~1" "%~2%~n1%$s%%~x1"& GoTo:EOF
fc/b "%~1" "%~2%~n1%$s%%~x1">nul&&(del/f/q "%~1"& GoTo:EOF)
set/a "$n+=1"& set "$s=0!$n!"& set "$s=_!$s:~-2!"
GoTo:MoveRen_Loop
P.S. имя папки должно быть без расширения (особенность алгоритма)
amel27, не понимаю зависимости, как добавить ещё несколько папок, не разберу из последнего скрипта.
нужно просто добавлять к
Call :MainExe Material3
Call :MainExe MaterialConst
новые папки
Call :MainExe Folder01
Call :MainExe Folder02
так ли это?
Tosyk, да
кстати, зря проигнорировали предложение forsem,
в отличие от XCOPY, у ROBOCOPY (http://ss64.com/nt/robocopy.html) есть ключ по перемещению папок
Работает чётко! Спасибо
а как сделать чтобы после перемещения удалялась исходная папка?
Допустим такая структура:
_export_
fold01
Material3
MaterialConst
MatsFull
fold02
Material3
MaterialConst
MatsFull
получается в папке _export_ после завершения операции 0 байт, я пробую удалить её командой
RD /S/Q _export_
написав её в конце скрипта, но скрипт просто игнорирует её.
p.s.: я не проигнорировал упоминание ROBOCOPY, просто во-первых я "тупо не шарю", извените за сленг, а во-вторых я считаю, что если взялся за что-то одно, его нужно завершить.
такая непонятность:
скрипт завис (не крашился а завис) на 814 файле и не идёт дальше.
касперский негодует
в диспетчере задач постоянно выскакивает и пропадает процесс fc.exe (http://winchanger.narod.ru/winprograms/fc.htm)
папки с файлами Material3 ещё есть
как сделать чтобы после перемещения удалялась исходная папка? »вариант с удалением успешно перемещенных папок:@echo off
SETLOCAL EnableDelayedExpansion
Call :MainExe Material3
Call :MainExe MaterialConst
EXIT
:MainExe %folder_name%
::---------------------
set "set $d="& if "%~1"=="" GoTo:EOF
for /f "delims=" %%d in ('dir/b/s/ad "%~1.*"') do if "%%~xd"=="" (
set "$e=0"& for /f "delims=" %%f in ('dir/b/s/a-d "%%d"') do (
set "$d=%%~dpf"& set "$d=!$d:%%~dpd=%%~dpd..\..\!"
call:MoveRen "%%f" "!$d!"||set/a $e+=1 )
if !$e!==0 rd /s/q "%%d" )
GoTo:EOF
:MoveRen %source_file% %destin_folder%
::-------------------------------------
set "$s="& set "$n="& if "%~1"=="" GoTo:EOF
if not exist "%~2" md "%~2"||exit/b 1
:MoveRen_Loop
if not exist "%~2%~n1%$s%%~x1" move "%~1" "%~2%~n1%$s%%~x1"&& GoTo:EOF||exit/b 2
fc/b "%~1" "%~2%~n1%$s%%~x1">nul&& (del/f/q "%~1"&& GoTo:EOF||exit/b 3)
set/a "$n+=1"& set "$s=0!$n!"& set "$s=_!$s:~-2!"
GoTo:MoveRen_Loop
Спасибо, а как быть с остановившимся процессом, касперский отключил, но ничего не изменилось?
p.s.: последний файл был M01_00.mat
как быть с остановившимся процессом »смотря что хотите, вообще анализ ошибок через запуск:script.bat >script.log 2>&1
...и смотрим лог "script.log", только в батнике предварительно поправить 1 строку: "@echo off" -> "@echo on"
P.S. антивирус может блокировать файлы и тем самым препятствовать их удалению/переименованию
Отключил антивирус, запустил скрипт снова, перемещено 3 500 файлов (вкупе 4 папки), полёт нормальный, в первый раз ошибок не заметил, постоянно наблюдал, на экране написано 1 file(s) moved - много раз.
p.s.: осталась самая полновесная папка - 56 000 элементов.
а с чем может быть связана невероятно низкая скорость работы скрипта? без касперского
примерно 2-3 файла в 5-9 минут
виндовс на компе несколько дней, никаких лишних программ не стоит даже офиса нет
© OSzone.net 2001-2012
vBulletin v3.6.4, Copyright ©2000-2025, Jelsoft Enterprises Ltd.