【问题标题】:How to move files via batch file but if file already exist move elsewhere?如何通过批处理文件移动文件但如果文件已经存在移动到其他地方?
【发布时间】:2018-09-23 01:03:15
【问题描述】:

我正在尝试将文件移动到特定文件夹 (目标文件夹),但我不想覆盖任何 文件。相反,如果该文件已经存在于该特定 文件夹(目标文件夹),然后将该文件移动到另一个 文件夹(溢出文件夹),但保持文件夹结构。

我尝试使用 xcopyrobocopy,但它似乎 不能那样做。

这是我用来移动文件但不覆盖的脚本。

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

【问题讨论】:

  • 当您的问题是批处理文件时,为什么要使用 Powershell 标签?

标签: windows batch-file robocopy xcopy


【解决方案1】:

现在看起来您的目标是获取一个文件夹或目录,并从该文件夹(包括子目录)中获取所有内容并将其复制到一个主文件夹。您希望将任何重复文件发送到溢出而不是被覆盖。

如果您不想覆盖任何文件,则可以使用溢出文件夹。但是,如果有两个重复的文件试图转储到溢出目录中怎么办?为了解决这个问题,我们可以简单地将 {File} 命名为 {File}(1){File}(2),例如。这部分脚本取自帖子上的michael_heath - batch script to copy files listed in a txt document and keep duplicates

基本上我们使用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"

【讨论】:

  • 这很好,也感谢 michael_heath,但是我看到的一个问题是它不保留文件夹结构,而是将所有内容转储到同一个主文件夹中,而不是被移动/复制到同一个主文件夹子文件夹。
  • @RoneJohnson 这就是让我失望的原因。如果您只是应对 A 文件夹,为什么需要溢出文件夹。所以你想检查目标中是否已经存在主目录?然后要么复制过来,要么发送到溢出(溢出也维护文件结构)?
  • 这些文件是时间戳敏感的,所以我不能覆盖它们。源中的文件是原始文件,我要移动到目标的文件也是原始文件,因此新的原始文件会在原始文件夹中找到它们的位置,并且复制或编辑的版本会溢出。我希望仅将文件夹结构保持到最后一个文件夹节点/名称。即 C:\house\folderwewanttokeep\files.mp4 到 G:\storage\folderwewanttokeep\files.mp4 文件夹“folderwewanttokeep”是我们要保留的文件夹路径的唯一部分。所以我们可以将“folderwewanttokeep\files.mp4”移动到我们决定的任何地方
【解决方案2】:
@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 到不同的分区是实际的 copydelete 成功 copycopy 总是copy

我实现了这两个操作,并且可以由 :copyfile 的被调用标签的第二个可选参数 通过传递"move""copy"。 如果参数不是"copy",则"move" 是默认值。

标签:copyfile 的第三个可选参数 是输出进度报告。 此参数如果定义,将echo 信息 (如路径等)关于操作。

标签:copyfile 的第一个参数是 要复制或移动的文件的路径。

for /r 循环递归source 目录和 使用找到的每个文件的路径调用:copyfile:copyfile 将设置 curpathsource 文件和 将destpath 设置为target 的路径,即 source 路径替换为 target 路径。 如果destpath 存在,则将destpath 设置为路径 到 overflow,这是替换的 source 路径 带有overflow 路径。如果destpath仍然存在,那么 标签已退出。

move 操作使用rd 删除空文件夹 来自source

copy 操作使用xcopy,因为它使 目标文件夹结构,以便不使用md。 传送到xcopyecho f 是回答"文件 还是文件夹?” 提示。

在脚本结束时,source 文件夹将被删除 如果为空。

设置sourcetargetoverflow变量 位于脚本顶部的实际路径。

查看set /? 中使用的变量替换 剧本。它用于替换源 目录路径与另一个目录路径, 创建目标路径。

【讨论】:

  • 谢谢似乎成功了,我觉得整个写出来的解释都没有,因为乍一看我有点不知所措,但当我阅读并逐行阅读时,一切都说得通了。跨度>
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2015-09-28
  • 2017-08-09
  • 1970-01-01
  • 2019-07-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多