CMD/BAT - Перенос каталогов и файлов

Ответить
Аватара пользователя
RealDT

CMD/BAT - Перенос каталогов и файлов

Сообщение RealDT »

Добрый день.



Друзья, необходимо выборочно перенести каталоги (и подкаталоги) и файлы в резервную папку.

Список выбранных каталогов сохранён в файле dir.txt, например:

Docs\!Каталог 1

Docs\Каталог 2

Docs\Каталог 3



Для выборочного переноса выполняется следующий код:



Код:

Код: Выделить всё

@echo off
cls
setlocal enabledelayedexpansion
set curdisk=%~d0
for /f "usebackq delims=" %%A in ("dir.txt") do (
    Set "folder_from="%curdisk%\%%A""
    set "folder_where="%curdisk%\%date:~6,4%-%date:~3,2%-%date:~0,2% reserv\%%A""
    if not exist !folder_where! md !folder_where!
    move /Y !folder_from!\*.* !folder_where!
    FOR /F "delims=" %%I IN ('DIR /B /AD !folder_from!') DO (
        move /Y !folder_from!\"%%I" %1 !folder_where!
    )
if exist !folder_from! rd !folder_from! | echo !folder_from!
)

Но если в названии выбранного каталога или в названии его подкаталогов имеется "!" (восклицательный знак), код не работает. Из названия каталогов/подкаталогов исчезает "!".



Если в файле dir.txt знак ! экранировать ^, код работает только с этим каталогом.

Docs\^!Каталог 1



Структура этого каталога может быть такой:

Docs\!Каталог 1

Docs\!Каталог 1\Папка 1!

Docs\!Каталог 1\!Папка 2

Docs\!Каталог 1\Папка !3

Docs\!Каталог 1\Папка 4

Т.е. ! знак может оказаться в любом месте в названии подкаталога и/или файлов.

Каким образом экранировать ! знак в подкаталогах и файлах этой папки? Может у кого есть другое решение по переносу заданных списком каталогов со всеми файлами?
Аватара пользователя
Iska

Re: CMD/BAT - Перенос каталогов и файлов

Сообщение Iska »

Цитата RealDT:



Может у кого есть другое решение по переносу заданных списком каталогов со всеми файлами?
CMD/BAT - Перенос каталогов и файлов




Есть несколько вариантов. Например, не использовать отложенное раскрытие переменных окружения. Перейти на WSH/PoSH.



Зачем Вы используете здесь:


Цитата:





Код:

Код: Выделить всё

if exist !folder_from! rd !folder_from! | echo !folder_from!





конвеер?!
Аватара пользователя
megaloman

Re: CMD/BAT - Перенос каталогов и файлов

Сообщение megaloman »

RealDT,
Цитата Iska:



не использовать отложенное раскрытие переменных окружения
CMD/BAT - Перенос каталогов и файлов




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

Код:

Код: Выделить всё

@Echo Off
cls
	Set "curdisk=%~d0"
	For /f "usebackq delims=" %%A in ("dir.txt") Do (
		RoboCopy "%curdisk%\%%A" "%curdisk%\%date:~6,4%-%date:~3,2%-%date:~0,2% reserv\%%~nxA" "*.*" /S /IS /Move
	)
Pause

До меня совершенно не доходит строка:
Цитата RealDT:



move /Y !folder_from!\"%%I" %1 !folder_where!
CMD/BAT - Перенос каталогов и файлов




Если моё извращение Вашего кода Вас не устраивает, объясните подробнее, что Вам надо.
Аватара пользователя
RealDT

Re: CMD/BAT - Перенос каталогов и файлов

Сообщение RealDT »

Спасибо за отклики.

По порядку:




Цитата Iska:



Перейти на WSH/PoSH
CMD/BAT - Перенос каталогов и файлов




мне такое пока не ведомо, посмотрю. если есть ссылки, просьба черкануть...



это



Код:

Код: Выделить всё

if exist !folder_from! rd !folder_from! | echo !folder_from!

нужно чтобы удалить выборочную папку (которая указана в dir.txt) c диска после переноса.



эта команда



Код:

Код: Выделить всё

move /Y !folder_from!\"%%I" %1 !folder_where!

переносит и каталоги и файлы. %1 - лишнее, можно не указывать




Цитата:



Если моё извращение Вашего кода Вас не устраивает, объясните подробнее, что Вам надо.



Предложенный Вами код работает. Но, если move переносит файлы, то robocopy их копирует. Команда move (а не copy & rd или robocopy) на физическом уровне работает в разы быстрее, поскольку работает только в секторах HDD, где размещены ссылки на содержание файлов, а не данные этих файлов. Другими словами - copy/robocopy резервирует и создаёт на диске новый блок данных, а move - только меняет ссылки на расположение этих данных. Скорость работы move и copy/robocopy хорошо видна на больших файлах и незаметна если файлов много, но они небольшого размера.



Вот код, который переносит (не копирует) один заданный каталог и обрабатывает также каталоги/файлы с восклицательными знаками:



Код:

Код: Выделить всё

set curdisk=%~d0
Set dir1=Docs\!КОНТАКТЫ
Set folder_from=%curdisk%\%dir1%
Set folder_where=%curdisk%\%date:~6,4%-%date:~3,2%-%date:~0,2% reserv\%dir1%
if not exist "%folder_where%" md "%folder_where%"
if exist "%folder_from%\*.*" move /Y "%folder_from%\*.*" "%folder_where%"
FOR /F "delims=" %%I IN ('DIR /B /AD "%folder_from%"') DO (move /Y "%folder_from%\%%I" %1 "%folder_where%")
if exist %folder_from% rd %folder_from%

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




Цитата:



объясните подробнее, что Вам надо.



Изначально решалось это:

Перенести избранные каталоги с их содержанием (подкаталоги и файлы) в резервную папку на текущем диске. Название диска не известно.
Аватара пользователя
megaloman

Re: CMD/BAT - Перенос каталогов и файлов

Сообщение megaloman »

RealDT,
Цитата:



Но, если move переносит файлы, то robocopy их копирует.



Как говорил мой начальник, не надо ля-ля. Изображение Robocopy c ключом /mov переносит файлы с путями, а /move и директори, но при этом они будут удалены из источника, если только пустые. Я проверял, работает.

Проделайте robocopy /? >c:\robocopy.txt и читайте описание команды в файле c:\robocopy.txt

У меня ощущение, что Вы не проанализировали результат выполнения моего кода. Либо не точно его повторили, без всех ключей. Он полностью решает поставленную задачу, в том числе и чтение папок из списка в файле
Аватара пользователя
RealDT

Re: CMD/BAT - Перенос каталогов и файлов

Сообщение RealDT »

Код проверял в двух вариантах:

- на небольших файлах, которых много (код отлично справился за неск секунд) и

- на файлах > 1.5 ГБ - robocopy их начинает копировать, на экране светится прогресс копирования, после некоторого ожидания на середине одного из файлов - прервал работу кода...
Аватара пользователя
megaloman

Re: CMD/BAT - Перенос каталогов и файлов

Сообщение megaloman »

RealDT, у меня нет большого опыта с RoboCopy, озвученные проблемы мне кажутся странными.


Тогда вот вариант для любого уровня вложенности подпапок на основе Move

[spoiler]Код:
[/spoiler]

Код: Выделить всё

@Echo Off
cls
	Set "Disk=%~d0"
	Set "List=%Disk%\dir.txt"
	Set "Backup=%Disk%\%Date:~6,4%-%Date:~3,2%-%Date:~0,2% reserv"
	For /f "usebackq delims=" %%D in ("%List%") Do (
		For /F "usebackq delims=" %%F In (`Dir "%Disk%\%%D\" /B /S /A:D 2^>nul^|Sort /R`) Do (
			Call :MyMove "%%~dpD" "%Backup%\" "%%F" 
		)
		Call :MyMove "%%~dpD" "%Backup%\" "%Disk%\%%D" 
	)
pause
GoTo :Eof
:MyMove
	If Not Exist %3 Exit /B 1
	Set "Out=%~3"
	Call Set "Out=%%Out:%~1=%~2%%"
	If Not Exist "%Out%" Md "%Out%"
	2>nul Move /Y "%~3\*.*" "%Out%\"
	Rd %3
GoTo :Eof
Аватара пользователя
RealDT

Re: CMD/BAT - Перенос каталогов и файлов

Сообщение RealDT »

Спасибо за варианты решения.

Вот ещё один вариант решения:





Код:

Код: Выделить всё

@echo off
set curdisk=%~d0
Set folder_where=%curdisk%\%date:~6,4%-%date:~3,2%-%date:~0,2% reserv
if not exist "%folder_where%" md "%folder_where%"
FOR /F "tokens=1,2* delims=;" %%I IN (dir.txt) DO (
    if not exist "%folder_where%\%%J" md "%folder_where%\%%J"
    move /Y "%curdisk%\%%I" "%folder_where%\%%J"
)

При этом структура файла dir.txt поменялась и должна быть такой:

Каталог1\!Папка11\!Папка111\Папка1111;Каталог1\!Папка11\!Папка111[/i]

Каталог1\!Папка12\!Папка121\Папка1121;Каталог1\!Папка12\!Папка121

Каталог2\Папка12\Папка!331;Каталог2\Папка12

Каталог3\Папка13\;Каталог3



Т.е.:

- в переменную %%I записывается каталог "что переносить";

- в переменную %%J записывается часть каталога "куда переносить", полный путь "куда переносить" будет таким %folder_where%\%%J



Отличия от начального варианта решения:

- убрал SETLOCAL enabledelayedexpansion, который удалял воскличательные знаки в именах каталогов и файлах;

- убрал внешний цикл FOR (оставил только один цикл);

- добавил неявную переменную %%J

- изменил структуру dir.txt, в котором каждая строка формирует значения для %%I и %%J.
Аватара пользователя
Iska

Re: CMD/BAT - Перенос каталогов и файлов

Сообщение Iska »

RealDT, только имейте в виду, что curdisk — не текущий диск, а диск, на котором находится пакетный файл.
Ответить

Вернуться в «Скриптовые языки администрирования Windows»