在批处理脚本中获取包含文件名中字符串的最新文件的绝对路径
Get absolute path of newest file containing string in filename in batch script
我有一个批处理文件,我想获取最新的 "manifest" 文件,所以我希望能够为此使用 for 循环,但我不确定是否正确语法。
这是我的:
for /R %imagePath% %%F in (*.manifest.*) do (set manFile=%%F)
哪个对 return "C:/some/path/to/file.manifest.ext" 正确,但不一定是最新的。我看到其他类似这个使用 dir
的问题,但后来我没有得到完整的路径。我用 dir
做的尝试看起来像:
for /R %imagePath% %%F in ('dir /od *.manifest.*.*') do (set manFile=%%F)
这没有给我预期的输出。
完成此任务的最佳方法是什么?
set "manFile="
for /f "tokens=2,*" %%a in ('
robocopy "%imagePath%" "%temp%" *.manifest.* /is /l /nocopy /s /njh /njs /ndl /nc /ns /ts
^| sort /r
') do if not defined manFile set "manFile=%%b"
这使用 for /f
来处理 robocopy
命令的输出,该命令将生成具有 UTC 时间戳的匹配文件列表,该时间戳将被反向排序,因此最新的文件将是首先在列表中。
MC ND 的解决方案很聪明。但是当我尝试使用“.”作为文件掩码时,我得到了错误的结果。原因是 robocopy
列出了来自 源文件夹和(虚拟)目标文件夹的相应文件,在本例中为 %TEMP%
。您可以通过将 /xx
开关添加到 robocopy
来解决这个问题,或者只使用一个空的目标文件夹。由于我不能 100% 确定 /xx
开关将始终有效,因此我为目标文件夹指定了一个随机名称(希望该名称不存在)。
原始代码的第二个缺点是 FOR
循环将不必要地执行到文件列表的末尾,该列表可以是任意长的。
以下代码修复了目标文件夹问题,在获得结果后缩短了循环,此外还导出了树中最年轻文件的文件名和时间戳:
@echo off
setlocal
set "srcpath=%~1"
if not DEFINED srcpath set srcpath=%CD%
set /A skip=%2 - 1
set opt=
if DEFINED skip if %skip%0 GTR 0 set "opt=skip=%skip%"
set MASK=*.manifest.*
for /f "%opt% tokens=1,2*" %%a in ('
robocopy "%srcpath%" %RANDOM%_%RANDOM% %MASK% /l /s /ts /njh /njs /ndl /nc /ns ^| sort /r
') do set "tstamp=%%a %%b" & set "youngestfile=%%c" & goto :ex
:ex
echo %youngestfile% %tstamp%
脚本现在最多可以接受 2 个参数。第一个参数是源文件夹,如果省略则默认为当前文件夹。第二个参数是数字,允许搜索第 n 个最小的文件。因此,例如 "lastfile . 2" 将 return 以当前文件夹为根的树中第二年轻的文件。这是 FOR
循环的副作用,从列表顶部开始使用最新的文件。
我有一个批处理文件,我想获取最新的 "manifest" 文件,所以我希望能够为此使用 for 循环,但我不确定是否正确语法。
这是我的:
for /R %imagePath% %%F in (*.manifest.*) do (set manFile=%%F)
哪个对 return "C:/some/path/to/file.manifest.ext" 正确,但不一定是最新的。我看到其他类似这个使用 dir
的问题,但后来我没有得到完整的路径。我用 dir
做的尝试看起来像:
for /R %imagePath% %%F in ('dir /od *.manifest.*.*') do (set manFile=%%F)
这没有给我预期的输出。
完成此任务的最佳方法是什么?
set "manFile="
for /f "tokens=2,*" %%a in ('
robocopy "%imagePath%" "%temp%" *.manifest.* /is /l /nocopy /s /njh /njs /ndl /nc /ns /ts
^| sort /r
') do if not defined manFile set "manFile=%%b"
这使用 for /f
来处理 robocopy
命令的输出,该命令将生成具有 UTC 时间戳的匹配文件列表,该时间戳将被反向排序,因此最新的文件将是首先在列表中。
MC ND 的解决方案很聪明。但是当我尝试使用“.”作为文件掩码时,我得到了错误的结果。原因是 robocopy
列出了来自 源文件夹和(虚拟)目标文件夹的相应文件,在本例中为 %TEMP%
。您可以通过将 /xx
开关添加到 robocopy
来解决这个问题,或者只使用一个空的目标文件夹。由于我不能 100% 确定 /xx
开关将始终有效,因此我为目标文件夹指定了一个随机名称(希望该名称不存在)。
原始代码的第二个缺点是 FOR
循环将不必要地执行到文件列表的末尾,该列表可以是任意长的。
以下代码修复了目标文件夹问题,在获得结果后缩短了循环,此外还导出了树中最年轻文件的文件名和时间戳:
@echo off
setlocal
set "srcpath=%~1"
if not DEFINED srcpath set srcpath=%CD%
set /A skip=%2 - 1
set opt=
if DEFINED skip if %skip%0 GTR 0 set "opt=skip=%skip%"
set MASK=*.manifest.*
for /f "%opt% tokens=1,2*" %%a in ('
robocopy "%srcpath%" %RANDOM%_%RANDOM% %MASK% /l /s /ts /njh /njs /ndl /nc /ns ^| sort /r
') do set "tstamp=%%a %%b" & set "youngestfile=%%c" & goto :ex
:ex
echo %youngestfile% %tstamp%
脚本现在最多可以接受 2 个参数。第一个参数是源文件夹,如果省略则默认为当前文件夹。第二个参数是数字,允许搜索第 n 个最小的文件。因此,例如 "lastfile . 2" 将 return 以当前文件夹为根的树中第二年轻的文件。这是 FOR
循环的副作用,从列表顶部开始使用最新的文件。