>目标:我想使用批处理文件将具有特定扩展名的最新文件从"源目录"复制到"目标目录"。最新文件可能位于源目录中的多个子目录下。
这个问题/答案正是我想要的,但是当指定/s
选项时,它似乎没有排序(正如此评论所建议的那样):
FOR /F "delims=|" %%I IN ('DIR "K:pathtpsourcedir*.ext" /B /S /O:D') DO SET NewestFile=%%I
copy "%NewestFile%" "C:pathtodestinationdir"
您可以单独测试DIR "K:pathtpsourcedir*.ext" /B /S /O:D
以查看它是否不排序。
我尝试过什么:这个命令本身确实有效:DIR "K:pathtpsourcedir*.ext" /S /B | sort
但我无法弄清楚如何在 for 循环中使用它(批处理文件在我确定错误之前退出 - 即使最后有一个pause
)。
有什么想法吗?
请参阅:目录文档
如果需要,可以从批处理文件中调用Powershell
。 此代码可以在较新版本的Powershell
上缩短。
for /F "delims=" %%G IN ('powershell "gci -rec | where { ! $_.PSIsContainer } | sort LastWriteTime | select -last 1 | Select-Object fullname"') do set NewestFile=%%G
完整答案:
cd /d "K:pathtosourcedir"
for /F "delims=" %%G IN ('powershell "gci -rec *.ext | where { ! $_.PSIsContainer } | sort LastWriteTime | select -last 1 | Select-Object fullname"') do set NewestFile=%%G
copy "%NewestFile%" "C:pathtodestdir"
一个简单的解决方案可能是
@echo off
setlocal enableextensions disabledelayedexpansion
set "root=K:pathtpsourcedir"
set "mask=*.ext"
for %%r in ("%root%.") do for /f "tokens=2,*" %%a in ('
robocopy "%%~fr" "%%~fr" "%mask%" /njh /njs /nc /ns /ts /s /ndl /nocopy /is /r:0 /w:0 /l
^| sort /r
^| cmd /v /e /c"(set /p .=&echo(!.!)"
') do set "lastFile=%%b"
echo Last file : "%lastFile%"
此代码使用robocopy
生成带有时间戳前缀的文件列表(开关只是请求没有作业标头、没有作业摘要、没有文件类、没有文件大小、时间戳、递归、没有目录列表、没有目录信息复制、包含相同的文件、不重试、不等待、不复制仅生成列表)。
然后,此时间戳前缀列表(UTFyyyy/mm/dd hh:mm:ss
上次文件写入)按相反顺序排序,以获取第一行中的最后一个文件。此行使用单独的cmd
实例进行检索(这避免了for /f
读取长数据列表的时间问题),因此for /f
只读取一行。
由于robocopy
行包含日期、时间和文件名,为了检索最后一个字段,我们请求for /f
检索两个标记:一个包含小时(将以%%a
形式存储)和直到行尾的其余文本(存储在%%b
中)
包括额外的for %%r
只是为了防止使用robocopy
出现常见问题。当我们引用路径以防止空格问题时,我们需要确保路径不会以反斜杠结尾,该反斜杠将转义路径的结束引号并使命令失败。
一切似乎都正常。我相信您的问题在于您原始函数的"delims=|"
语句。通过使用"delims="
它所做的只是切断循环输出的第一个|
。由于|
不在正常的Windows文件路径中,因此完全不需要。尝试在语句中抛出一个"tokens=*"
。
我还建议使用Set "String="
而不是传统的Set String=
,因为在许多情况下,空格可能是一个问题。我在函数中更新了它。
批处理脚本:
@ECHO OFF
Rem | Configuration
Set "MainDirectory=C:Folder1"
Set "FileExtension=*.txt"
Set "CopyDestination=C:Folder2"
Rem | Search for the newest file in a directory/sub-directory
for /f "tokens=*" %%A in ('DIR "%MainDirectory%%FileExtension%" /B /S /O:D') do (SET "NewestFile=%%A")
Rem | Copy file to a destination
copy "%NewestFile%" "%CopyDestination%"
goto :EOF