如何在 Windows 中选择性地复制和重命名文件?

如何在 Windows 中选择性地复制和重命名文件?

基本上,在自动批处理文件中,如果目标文件丢失或较旧,我想复制并重命名文件。有几种变体,但效果不佳:

copy /Y c:\source\a.file c:\dest\b.file 

- 总是复制,没有/D 选项或其他东西

xcopy /Y /D c:\source\a.file c:\dest\b.file

- 如果目标不存在,则尝试询问目标是否是文件或目录,从而对自动构建造成严重破坏。

robocopy /XO ... 

- 不支持重命名文件。

看来 Windows 在 20 多年来都无法复制 Unix 的“cp -u”,还是我忽略了什么?

答案1

这可能超出了您的需要,但经过适当的调整,它应该可以完成工作。我做了一些实验,似乎如果您使用带有 /D 选项的 xcopy 并指定目标文件名,无论文件是否相同,您都会得到一个副本。(似乎它基于目标文件名而不是源文件名进行比较。)所以我只使用 xcopy 进行比较,但实际上并没有进行复制。(感谢 selbie 建议使用 /L 选项。)它看起来很大,但如果您删除注释,它就很小了。此示例使用当前日期和时间复制和重命名目标中存在但较新的文件。它复制但不重命名目标中不存在的文件(可以轻松更改)。并且不复制相同的文件。我可以帮助您修改它以满足您的特定需求。

@ECHO OFF
REM ### Note that this assumes all filenames end with ".txt".  This can be changed to suit your needs ###

REM ### Needed so the variables will expand properly within the FOR DO loops ###
Setlocal EnableDelayedExpansion

REM ### Set the source file(s) and call the "CopyIt" subroutine ###
SET Sourcefile=Test 1.txt
CALL :CopyIt

SET Sourcefile=Test2.txt
CALL :CopyIt

REM ### End of the program.  Otherwise the subroutine will run again ###
REM ### You can also just put an "EXIT" command here ###
GOTO END

REM ### The subroutine ###
:CopyIt
    REM ### Set the date and time to a variable called "DaTime" and remove offending ###
    REM ### characters (/ and :) that can't be used in a filename ###
    FOR /f "tokens=1-4 delims=/ " %%a in ("!date!") do SET DaTime=%%b-%%c-%%d
    FOR /f "tokens=1-3 delims=':'" %%e in ("!time!") do SET DaTime=!DaTime!_%%e-%%f-%%g

    REM ### Set a variable called "DestFile" to source filename minus ".txt" ###
    REM ### to be used to set the new destination file name + "DaTime" ###
    SET Destfile=!Sourcefile:.txt=!

    REM ### Check to see if the source filename exists in the destination directory ###
    DIR "C:\_Dest\!Sourcefile!" > NUL
    IF !ErrorLevel!==0 (
        REM ### If it does exist, set the loop count to 0 ###
        SET /a Count=0
        REM ### Have xcopy check to see if the source file is newer, but only report and not copy ###
        REM ### Thanks to selbie for suggesting the /L option ###
        FOR /f "tokens=1 delims=0" %%s in ('xcopy /Y /D /L "C:\_Source\!Sourcefile!" "C:\_Dest\"') DO (
            REM ### Increment the loop count ###
            SET /a Count=!Count!+1
            REM ### Only pick up the first iteration.  If the files are different, it will be the full path and the filename ###
            If !Count!==1 SET Source=%%s
        )
        REM ### If the source is the same as the destination, then !Source! will = " File(s)".  Change it to NONE ###
        SET Source=!Source: File^(s^)=NONE!
        REM ### If it's not equal to NONE, copy the file and rename it to source file + date & time + .txt ###
        IF !Source! NEQ NONE COPY /Y "!Source!" "C:\_Dest\!Destfile!-!DaTime!.txt"
    ) ELSE (
        REM ### If it does not exist, copy the file without renaming it ###
        COPY /Y "C:\_Source\!Sourcefile!" "C:\_Dest\"
    )
REM ### Exit the subroutine ###
EXIT /b

:END
pause

答案2

创建一个包含一行字母的文件f(随便叫什么名字,对于这个答案来说它将是f.txt)。

将内容通过管道传输f.txt到 xcopy 命令:

xcopy /Y /D c:\source\a.file c:\dest\b.file<f.txt

(F = file, D = directory)?当文件不存在时,这将提供出现提示的答案。

**编辑:**刚刚意识到这基本上重复了 Rik 对问题的评论的功能,只是他的回答更简洁。

答案3

也许是这个:

xcopy /I /Y /D c:\source\a.file c:\dest\b.file

答案4

您可以尝试以下操作:

xcopy "c:\source\a.file" "c:\dest\b.file*" /A /Y 
  • /Y 删除提示覆盖
  • 新文件末尾的“*”删除提示“文件或目录”

祝你好运!

相关内容