Windows cmd cd 进入最新目录

Windows cmd cd into newest directory

我有一个包含子目录的部署目录,每个部署一个。我正在尝试编写一个批处理脚本,除其他外,它对这些目录中的最新目录执行 cd

我知道如何在 bash 中做到这一点(也已经回答 ),但我不知道如何在 Windows 中完成同样的事情 cmd。谁能帮帮我?

在批处理文件中,可以使用以下行更改为具有最新修改日期的子目录:

@echo off
for /F "eol=| delims=" %%I in ('dir * /AD /B /O-D 2^>nul') do cd "%%I" & goto DoneCD
echo No subdirectory found in: "%CD%"
:DoneCD

带有选项 /F 的命令 FOR 启动一个新的命令进程,其中 %ComSpec% /c' 之间指定的命令行作为进一步的参数在后台。因此 FOR 执行的是通常的 Windows 安装路径:

C:\Windows\System32\cmd.exe /c dir * /AD /B /O-D 2>nul

DIR 由后台命令进程执行搜索指定参数

  • 在当前目录
  • 用于目录,因为选项 /AD(属性目录)
  • 匹配通配符模式*(全部)

并输出

  • 由于选项 /B 的裸格式只是没有路径的目录名称从未包含在 "
  • 由于选项 /O-D 而未使用选项 /TC(创建日期)或 /TA(最后访问日期),因此按最后修改日期反向排序,这意味着首先是最新修改的目录最后一个最旧的修改目录。

DIR 的输出被写入处理已启动后台命令进程的 STDOUT

2>nulDIR 在当前目录中找不到任何目录的错误消息从句柄 STDERR 重定向到设备NUL 以抑制此错误消息。

阅读有关 Using Command Redirection Operators 的 Microsoft 文章,了解 2>nul 的解释。重定向运算符 > 必须在 FOR 命令行上使用脱字符 ^ 进行转义,以便在 Windows 命令解释器处理此命令时将其解释为文字字符执行命令 FOR 之前的行,它在后台启动的单独命令进程中执行嵌入式 dir 命令行。

FOR 捕获由 DIR 编写的所有内容以处理启动命令进程和进程的 STDOUT此输出在开始后逐行 cmd.exe 自行终止。

FOR 忽略此处不出现的空行,因为 DIR 输出没有空行的目录名称列表,因为使用 /B.

FOR 默认情况下会将一行拆分为子字符串(标记),使用普通 space 和水平制表符作为分隔符。完成此子字符串拆分后,FOR 将默认检查第一个子字符串是否以默认行尾字符 ; 开头,在这种情况下,该行将像空行一样被忽略。否则 FOR 会将第一个 space/tab 定界字符串分配给指定的循环变量 I 并使用 CD 执行命令行和 GOTO.

目录名称可以是例如  ;Test Folder,即目录名称以 space 和一个分号开头,然后再包含一个 space。这样的目录名称将被拆分为 ;Test(开头没有 space)和 Folder,然后被 FOR 忽略,因为 ;Test 以分号开头。

出于这个原因,行尾字符从默认的分号重新定义为带有 eol=| 的竖线,根据有关 Naming Files, Paths, and Namespaces 的 Microsoft 文档,这是一个文件或文件夹名称不能包含的字符。并且在 for /F 之后的选项参数字符串末尾使用 delims= 禁用行拆分行为,它定义了一个空的分隔符列表。因此,DIR 输出的目录名称被分配给循环变量 I,即使是一个非常不寻常的目录名称也没有任何修改。

FOR 执行命令 CD 将当前目录更改为当前目录的最后修改的子目录和下一个命令 执行GOTO,继续处理标签行:DoneCD下一行的批处理文件。因此,在使用命令 GOTO.

处理第一个目录名称后,FOR 循环执行已经中断

当然可以在 FOR 命令行和标签行 :DoneCD 之后使用其他命令,而不仅仅是 ECHO 行报告在当前目录中没有找到子目录,如引用动态环境变量 CD 所示,就像命令行一样退出批处理这个不寻常的用例或错误条件案例。

这个FOR命令行用命令GOTO退出FOR循环后CD 不能在 Windows 命令提示符 window 中使用。 Windows 命令提示符 window 的解决方案是:

set "DoneCD=" & (@for /F "eol=| delims=" %I in ('dir * /AD /B /O-D 2^>nul') do @if not defined DoneCD cd "%I" & set "DoneCD=1") & set "DoneCD="

在批处理文件中,此 single line with multiple commands 将写为

@set "DoneCD=" & (@for /F "eol=| delims=" %%I in ('dir * /AD /B /O-D 2^>nul') do @if not defined DoneCD cd "%%I" & set "DoneCD=1") & set "DoneCD="

或在其 multi-line 版本中增加了一个 echo 作为

更好的可读性
@echo off
set "DoneCD="
for /F "eol=| delims=" %%I in ('dir * /AD /B /O-D 2^>nul') do (
    if not defined DoneCD (
        cd "%%I"
        set "DoneCD=1"
    )
)
if not defined DoneCD echo No subdirectory found in: "%CD%"
set "DoneCD="

首先删除环境变量DoneCD,如果它是偶然定义的。

下一个 FO 使用 DIR 运行 cmd.exe 如上所述,并处理具有最新修改日期的第一个输出目录。 IF 条件在最新目录上为真,因为在执行 FOR 之前环境变量肯定是未定义的。所以执行命令 CD 将当前目录更改为最新的子目录。然后环境变量 DoneCD 被定义为值 1。任何其他值也可能像使用 set "DoneCD=%%I" 一样。这里重要的是,对于 DIR 输出的其他子目录,环境变量 DoneCD 现在已定义,因此 IF 条件始终为假.因此,没有尝试将初始当前目录的当前子目录更改为此处不存在或子目录中偶然存在的子目录。

最后,如果在执行 FOR.

期间定义了环境变量 DoneCD,则会再次删除

要了解使用的命令及其工作原理,请打开命令提示符 window,在其中执行以下命令,并仔细阅读为每个命令显示的所有帮助页面。

  • cd /?
  • dir /?
  • echo /?
  • for /?
  • goto /?
  • if /?
  • set /? ... 在上一个帮助页面上解释动态环境变量 CD