目标:我想使用批处理文件将具有特定扩展名的最新文件从“源目录”复制到“目标目录”。最新文件可能位于源目录中的几个子目录下。
This question/answer正是我想要的,但是当指定/s
选项(如this comment would suggest)时,它似乎没有排序:
FOR /F "delims=|" %%I IN ('DIR "K:\path\tp\source\dir\*.ext" /B /S /O:D') DO SET NewestFile=%%I
copy "%NewestFile%" "C:\path\to\destination\dir"
您可以单独测试DIR "K:\path\tp\source\dir\*.ext" /B /S /O:D
来查看它是否排序。
我尝试过的事情:该命令本身确实有效:DIR "K:\path\tp\source\dir\*.ext" /S /B | sort
,但我不知道如何在for循环中使用它(批处理文件在退出之前就可以退出了)确定错误-即使结尾处带有pause
。
有什么想法吗?
请参阅:dir docs
答案 0 :(得分:1)
如果需要,您可以从批处理文件中调出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:\path\to\source\dir"
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:\path\to\dest\dir"
答案 1 :(得分:1)
一个简单的解决方案可能是
@echo off
setlocal enableextensions disabledelayedexpansion
set "root=K:\path\tp\source\dir"
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
生成带有时间戳前缀的文件列表(交换机仅请求无作业头,无作业摘要,无文件类,无文件大小,时间戳,递归,无目录列表,没有目录信息副本,包括相同的文件,没有重试,没有等待,不要只复制生成列表。
此时间戳前缀列表(UTF yyyy/mm/dd hh:mm:ss
最后写入文件)然后以相反的顺序排序,以获取第一行中的最后一个文件。使用单独的cmd
实例检索该行(这避免了for /f
读取较长数据列表的时间问题),因此for /f
仅读取一行。
由于robocopy
行包含日期,时间和文件名,要检索最后一个字段,我们请求for /f
检索两个令牌:一个包含小时(将存储在{{ 1}}),其余文本直到行尾(存储在%%a
中)
包含附加的%%b
只是为了防止使用for %%r
时出现常见问题。在引用路径以防止空格问题时,我们需要确保路径不以反斜杠结尾,以使路径的右引号转义并使命令失败。
答案 2 :(得分:0)
一切似乎都正常。我相信您的问题出在原始功能的fit_generator
语句中。通过使用"delims=|"
,它所要做的就是从循环输出中切除第一个"delims="
。由于|
不在正常的Windows文件路径中,因此完全不需要。尝试只在语句中抛出|
。
我还建议使用"tokens=*"
代替传统的Set "String="
,因为在许多情况下空格可能会成为问题。我在功能中对此进行了更新。
批处理脚本:
Set String=