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

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

Я пробовал с xcopy и robocopy, но похоже, что этого нельзя сделать.

Это скрипт, который я использую для перемещения файлов, но не перезаписываю.

robocopy "C:\DummySourcePath\" "C:\DummyDestantionPath\" /E /XC /XN /XO

Ответы [ 2 ]

0 голосов
/ 23 сентября 2018
@echo off
setlocal

set "source=%cd%\source"
set "target=%cd%\target"
set "overflow=%cd%\overflow"

for /r "%source%" %%A in (*.*) do call :copyfile "%%~A" "move" "report"

2>nul rd "%source%"
exit /b

:copyfile  source [, operation [, report]]
setlocal
set "curpath=%~1"
set "operation=%~2"
set "report=%~3"

if defined report echo "%curpath%"

call set "destpath=%%curpath:%source%=%target%%%"
if exist "%destpath%" call set "destpath=%%curpath:%source%=%overflow%%%"

if exist "%destpath%" (
    if defined report echo     exist in "%destpath%"
    exit /b 1
)

if "%operation%" == "copy" (
    if defined report echo     copy to "%destpath%"
    echo f|>nul xcopy "%curpath%" "%destpath%"
) else (
    for %%A in ("%destpath%") do (
        if not exist "%%~dpA" md "%%~dpA" || (
            if defined report echo     md failed with "%%~dpA"
            exit /b 1
        )
    )

    if defined report (
        echo     move to "%destpath%"
        move "%curpath%" "%destpath%"
    ) else >nul move "%curpath%" "%destpath%"

    for %%A in ("%curpath%") do 2>nul rd "%%~dpA"
)
exit /b 0

move в том же разделе - это перемещение только в таблице основных файлов.move для другого раздела является действительным copy и delete при успешном copy.copy всегда выполняет copy.

Я реализовал обе операции и может быть установлен вторым необязательным аргументом для вызываемой метки :copyfile, передав "move" или "copy"."move" по умолчанию, если аргумент не "copy".

Третий необязательный аргумент для метки :copyfile - вывод отчета о ходе выполнения.Этот аргумент, если он определен, будет echo информацией ( как пути и т. Д. ) о операции.

1-й аргумент метки :copyfile - это путь к файлу, который нужно скопироватьили перемещено.

Цикл for /r рекурсивно обращается к каталогу source и вызывает :copyfile с путем к каждому найденному файлу.:copyfile установит curpath в файл source и установит destpath в качестве пути к target, то есть пути source, замененному на путь target.Если существует destpath, то для destpath задается путь к overflow, то есть путь source заменяется на путь overflow.Если все еще destpath существует, то метка закрывается.

Операция move использует rd для удаления пустых папок из source.

Операция copy использует xcopy, поскольку он создает структуру папок назначения, поэтому md не используется.echo f, переданный на xcopy, отвечает на приглашение «файл или папка?» .

В конце сценария папка source будет удалена, если она пуста.

Установите переменные source, target и overflow в верхней части скрипта для фактических путей.

Просмотр set /? о подстановке переменных, используемой в скрипте.Он используется для замены пути к исходному каталогу другим путем к каталогу, чтобы создать путь назначения.

0 голосов
/ 23 сентября 2018

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

Если вы не хотите перезаписывать какие-либо файлы, будет работать папка переполнения.Однако что, если есть два дубликата файлов, которые пытаются сбросить в каталог переполнения?Чтобы обойти это, мы можем просто назвать {File} to {File} (1) , {File} (2) , exc.Эта часть сценария была взята из michael_heath пакетного сценария post - для копирования файлов, перечисленных в текстовом документе, и сохранения дубликатов .

По сути, мы используемFOR /R оператор вместе с IF оператором, чтобы проверить, содержит ли каталог target файл или нет.Если это произойдет, ELSE переместит его в переполнение с дополнительными средствами защиты от переполнения.

@ECHO OFF
@setlocal enableextensions enabledelayedexpansion

rem | Configure directories
set "source=C:\Source-Directory"
set "target=C:\Target-Directory"
set "overflow=Overflow-Directory"

rem | Scan target directory for a duplicate file name.
rem | If a duplicate was found, run a function to copy it to a overflow directory.
rem | If it already exists in the overflow directory rename it to {Name}(1), {Name}(2), exc.
rem | The overflow {Name}(1) protection was originally scripted by: michael_heath
FOR /R "%source%" %%i in (*.*) do (
If not exist "%target%\%%~nxi" (copy "%%i" "%target%") ELSE (call :index "%%~i" "%overflow%\%%~nxi" "1"))

rem | Run finished code here or end script with "goto :eof"
goto :eof

:index  source, overflow, count
setlocal
set /a "cnt=%~3"

if exist "%overflow%\%~n2(%cnt%)%~x2" (
    call :index "%~1" "%~2" "%cnt%+1"
) else copy "%~1" "%overflow%\%~n2(%cnt%)%~x2"
...