复制文件夹结构,但仅限最新文件

时间:2019-07-01 20:36:45

标签: powershell batch-file robocopy

我有许多编号目录,每个目录包含一组文件:

Folder_abc  
   index.xml
   000001.doc
   000002.doc
   000003.doc
   000004.doc

Folder_bdf
   index.xml
   000001.xls
   000002.xls 

Folder_...

所需结果(仅最新版本)

Folder_abc
  index.xml
  000004.doc
Folder_bdf
  index.xml
  000002.xls 
Folder_...

每个目录中都有一个index.xml当然可以将其复制到robocopy,必要时也可以单独复制

我正在寻找的解决方案,尽管我没有找到解决方法,但最好使用

2 个答案:

答案 0 :(得分:0)

我假设最多的文件可能是任意天数?是真的吗?

如果所有目录在单个根文件夹上只有1层深,则:

 @(
   SetLocal EnableDelayedExpansion
   Echo Off
 )
 SET "_Root=C:\Some\Folder\Path"
 SET "_NewRoot=C:\Some\New\Folder"

 For /D %%A In ("_Root") Do (
   MD "%_NewRoot%\%%A"
   Copy  "%_Root%\%%A\index.xml" "%_NewRoot%\%%A\index.xml"
   For /F "Tokens=*" %%a IN ('DIR /A-D /B /OD "_Root\%%A\" ^| FindStr /I /V /C:"index\.xml$"') Do (
     SET "_File=%%a"
   )
  Copy  "%_Root%\%%A\!_File!" "%_NewRoot%\%%A\!_File!"
)

因此,从本质上讲,我们需要循环目录结构并将_File变量的值设置为找到的文件,并且,如果我们按日期升序排列它们,则找到的最后一个值将是最新的文件夹,因此当我们从该循环中退出,该变量已使用您需要的值填充。

因为总是需要索引,所以我立即创建文件夹并复制索引,并且仅在找到匹配项后才进行第二个文件复制,我们会忽略“ Index.xml”,因为它已经复制了,无论如何都不适合匹配的最新文件

答案 1 :(得分:0)

这基本上是来自my comment的代码,带有一些解释性说明和较小的更正,即从内部循环处理的文件中排除index.xml

@echo off
rem // Define constants here:
set "ROOT=D:\Path\To\Source"
set "DEST=D:\Path\To\Destination"
set "NAME=Folder_*"  & rem // (name/mask of source sub-directories)
set "FILE=index.xml" & rem // (name of file that must always be copied)

rem // Loop over all sub-directories in the root source directory:
for /D %%D in ("%ROOT%\%NAME%") do (
    rem // Reset variable that will hold name of file to copy later:
    set "LAST="
    rem /* Get all files in sorted manner, except the one that must always be copied;
    rem    store the name in a variable, which will hold the last file name finally;
    rem    `/O:D` regards the last modification date; add `/T:C` for the creation date;
    rem    to sort by name rather than by date, replace `/O:D` by `/O:N` or `/O:NE`: */
    for /F "delims= eol=|" %%F in ('
        2^> nul dir /B /A:-D /O:D "%%~D\*.*" ^| findstr /I /V /C:"%FILE%"
    ') do set "LAST=%%F"
    rem /* Create destination sub-directory with the same name as the source sub-directory;
    rem    potential error message in case the sub-directory already exists are suppressed: */
    2> nul md "%DEST%\%%~nxD"
    rem // Copy the file that always needs to be copied, if there is such:
    if exist "%%~D\%FILE%" copy /-Y "%%~D\%FILE%" "%DEST%\%%~nxD\"
    rem // Copy the previously determined last file, if any has been found:
    if defined LAST call copy /-Y "%%~D\%%LAST%%" "%DEST%\%%~nxD\"
)