将以前的版本复制并重命名为上次修改

时间:2017-05-29 20:49:37

标签: windows batch-file cmd

对于批量复制的目的,我需要创建一个我认为简单的脚本,但没有运气。

用例是:将所有文件从sourcedirectory复制到targetdirectory,其中sourcedirectory文件在targetdirectory中不存在,但如果targetdirectory中已存在该文件,则在复制前将其重命名为original_name.B<timestamp_last_modified> /覆盖

我的开始:

xcopy %sourcedirectory% %targetdirectory% /f /i /s /h /d /y >> W:\Xcopy%datetimefile%.log 2>&1

但它不能重命名部分,所以我开始玩游戏到达这里:

@echo off
rem configuration
set sourcedirectory="d:\Ice"
set targetdirectory="W:\Ice"
set logdirectory="W:"

rem following part only creates timestamp for log file (datetimefile) and log record (datetimecopy)
for /f "tokens=2 delims==" %%I in ('wmic os get localdatetime /format:list') do set datetimefile=%%I
set datetimecopy=%datetimefile:~0,8% %datetimefile:~8,2%:%datetimefile:~10,2%:%datetimefile:~12,2%
set datetimefile=%datetimefile:~0,8%_%datetimefile:~8,6%
set "logfile=%logdirectory:~0,-1%\Backup%datetimefile%.log^""

rem logging
echo Log File is %logfile%
echo -----     BACKUP FROM: %sourcedirectory% TO: %targetdirectory% AT: %datetimecopy%     -----
echo -----     BACKUP FROM: %sourcedirectory% TO: %targetdirectory% AT: %datetimecopy%     ----- >> %logfile% 2>&1

rem execution
for /F "tokens=*" %%A in ('xcopy %sourcedirectory% %targetdirectory% /f /i /s /h /d /y /l') do (call :subroutine "%%A")

rem log timestam creation and logging
for /f "tokens=2 delims==" %%I in ('wmic os get localdatetime /format:list') do set datetimecopy=%%I
set datetimecopy=%datetimecopy:~0,8% %datetimecopy:~8,2%:%datetimecopy:~10,2%:%datetimecopy:~12,2%
echo -----     BACKUP FINISHED AT: %datetimecopy%     -----
echo -----     BACKUP FINISHED AT: %datetimecopy%     ----- >> %logfile% 2>&1

goto :finish

:subroutine
 set "f=%1"
 set "f=%f:~1,-1%"
 set "filefrom=%f: -> =" & set "fileto=%"
 set "filefrom=^"%filefrom%^""
 set "fileto=^"%fileto%^""
 if NOT EXIST %fileto% GOTO :cpyonly
 set "g=%fileto%"
 call set "newg=%%g:\=\\%%"
 for /f "tokens=2 delims==" %%N in ('wmic datafile where name^=%%newg%% get LastModified /format:list') do set lastmod=%%N
 set "i=%fileto%"
 set "target="%%~ni%%~xi.B%lastmod:~0,14%^""
 echo rename %g% %target%
 echo "rename %g% %target%" >> %logfile% 2>&1
 rename %g% %target% >> %logfile% 2>&1
 goto :cpyonly

:cpyonly
 echo "xcopy %filefrom% %fileto% /f /h /d /y"  >> %logfile% 2>&1
 echo xcopy %filefrom% %fileto% /f /h /d /y
 xcopy %filefrom% %fileto% /f /h /d /y >> %logfile% 2>&1
 GOTO :finish

rem :testing
rem wmic datafile where name="d:\\CopyFrom\\drziaky.txt" get LastModified /format:list
rem d:\Ice\Private\StartBatch\Backup_new.bat

:finish

然而,它没有奏效,无法前进,观察到的问题:

  1. 文件名包含空格,即使我使用了"tokens=*",它也会在文件中创建拆分我还没有找到如何将整个%%A传递给子程序的方法
  2. 通过文件操作,我有时需要删除或添加“”,这适用于某些位置而某些位置,但是我没有发现何时/为什么(例如此set "f=%f:~1,-1%"旨在删除“这个set "fileto=^"%fileto%^""旨在添加它们
  3. 以前的版本(不是在这篇文章中,但是将它们放在我的硬盘上):

    1. 我尝试使用副本,但副本没有创建目标目录
    2. wmic命令因地方差异而被使用,似乎有用(获取时间和最后修改日期)
    3. xcopy作为列表​​生成器工作(小问题,最后一行列出文件数)
    4. 首先通过for /f尝试解析,然后通过set "filefrom=%f: -> =" & set "fileto=%"(从here复制)尝试解析
    5. 以下是最后一个工作代码(带副本)但是:

      • 无法创建目标目录
      • 中断文件名中的空格
      • 在xcopy的最后一行(复制的X文件)中断

      也许它在其他一些情况下也会中断,但这是我迄今为止所能达到的最好的情况,但是如果陷入困境并无法从这一点向前推进,有人可以帮助我吗?谢谢你,并为长篇大论道歉。如果它已经在这里,那么我真的很盲目,因为你花了很多时间搜索。

      PS:enabledelayedexpansion无法使用:-(也不能使用第三方,所以脚本只能是1个文件

      set sourcedirectory="d:\Ice"
      set targetdirectory="W:\Ice"
      set logdirectory="W:"
      for /f "tokens=2 delims==" %%I in ('wmic os get localdatetime /format:list') do set datetimefile=%%I
      set datetimecopy=%datetimefile:~0,8% %datetimefile:~8,2%:%datetimefile:~10,2%:%datetimefile:~12,2%
      set datetimefile=%datetimefile:~0,8%_%datetimefile:~8,6%
      set "logfile=%logdirectory:~0,-1%\Backup%datetimefile%.log^""
      echo -----     BACKUP FROM: %sourcedirectory% TO: %targetdirectory% AT: %datetimecopy%     ----- >> %logfile% 2>&1
      
      for /f "tokens=1,3" %%A in ('xcopy %sourcedirectory% %targetdirectory% /f /i /s /h /d /y /l') do (call :subroutine "%%A" "%%B")
      
      for /f "tokens=2 delims==" %%I in ('wmic os get localdatetime /format:list') do set datetimecopy=%%I
      set datetimecopy=%datetimecopy:~0,8% %datetimecopy:~8,2%:%datetimecopy:~10,2%:%datetimecopy:~12,2%
      echo -----     BACKUP FINISHED AT: %datetimecopy%     ----- >> %logfile% 2>&1
      
      goto :eof
      
      :subroutine
       set "f=%1"
       if NOT EXIST %2 GOTO :cpyonly
       set "g=%2"
       call set "newg=%%g:\=\\%%"
       for /f "tokens=2 delims==" %%N in ('wmic datafile where name^=%%newg%% get LastModified /format:list') do set lastmod=%%N
       set "target="%~n2%~x2.B%lastmod:~0,14%^""
       echo "rename %g% %target%" >> %logfile% 2>&1
       rename %g% %target% >> %logfile% 2>&1
       goto :cpyonly
      
      :cpyonly
       echo "copy %1 %2" >> %logfile% 2>&1
       copy %1 %2 >> %logfile% 2>&1
       GOTO :eof
      
      :eof
      

1 个答案:

答案 0 :(得分:0)

所以最后几个小时后我找到了解决方案,现在它按照我的预期工作,还添加了ziping的旧文件。 如果有人想要使用感觉自由。它是如何工作的,它检查所有文件,并将目标上不存在的文件复制到目标,如果文件存在于目标上,则将其重命名为上次修改日期和ziped(这里需要设置自己的拉链和参数),然后复制新文件,最后再次执行xcopy作为安全措施,以防我的脚本对某些文件失败。

@Inject