繁体   English   中英

对于 /d /r 循环不遍历子目录以在 Batch/CMD 脚本中递归查找所需目录

[英]For /d /r loop not traversing sub-directories for finding desired directory recursively in Batch/CMD script

如问题标题中所述,如果传递给脚本的参数是 Chrome,我有一个 Batch/CMD(OS: Windows 10 64Bit) 脚本来遍历%LocalAppData%内的子文件夹,并递归查找并列出所有包含单词Cache的文件夹position。

我想出的依赖for /d /r循环的脚本是这样的:

@echo off && setlocal EnableDelayedExpansion
if /i "%1" equ "chrome" (
    set "subPath0=\Google"
    set "subPath1=\User Data"
    for /d /r "%LocalAppData%!subPath0!\%1" %%i in (*Cache*) do (
        echo "%%i"
    )
) else (
    for /d /r "%Appdata%\%1" %%i in (*Cache*) do (
        echo "%%i"
    )
)

但无论我是否像(*Cache*^)那样转义for循环内的右括号,上述循环都没有递归列出任何*Cache*目录,即使路径内实际上有Cache文件夹(其中for循环正在运行)在User Data文件夹中。

那么谁能指出我在这里做错了什么并帮助解决这个问题?

注意:我知道 Powershell 是 Batch/CMD 的不错选择,但这应该是较大脚本的一部分,所以如果在 Batch/CMD 中提出建议/修复,将不胜感激。

FOR命令中删除路径并改用 PUSHD。

@echo on
setlocal EnableDelayedExpansion
if /i "%1" equ "chrome" (
    set "subPath0=\Google"
    set "subPath1=\User Data"
    pushd "%LocalAppData%!subPath0!\%~1"
    for /D /R %%i in (*Cache*) do (
        echo "%%i"
    )
    popd
) else (
    pushd "%Appdata%\%1"
    for /d /r %%i in (*Cache*) do (
        echo "%%i"
    )
    popd
)

为什么不将其简化为一个FOR命令?

@echo on
setlocal EnableDelayedExpansion
if /i "%~1" equ "chrome" (
    set "subPath0=\Google"
    set "subPath1=\User Data"
    set "searchpath=%LocalAppData%!subPath0!\%1"

) else (
    set "searchpath=%Appdata%\%~1"
)

for /d /r "%searchpath%" %%i in (*Cache*) do echo "%%i"

我强烈建议使用:

@echo off & setlocal EnableExtensions DisableDelayedExpansion
if /I not "%~1" == "chrome" goto SearchAppdata

for /D /R "%LocalAppData%\Google\%~1" %%i in (*Cache*) do echo "%%i"
goto EndBatch

:SearchAppdata
for /D /R "%Appdata%\%~1" %%i in (*Cache*) do echo "%%i"

:EndBatch
endlocal

所有变化的解释:

  1. 命令echo off永远不会失败,因此在第一行使用无条件运算符&代替条件运算符&& 有关详细信息,请参见使用 Windows 批处理文件的单行多命令

  2. 批处理文件需要启用命令扩展。 出于这个原因,建议显式启用命令扩展并且不要依赖于在批处理文件之外启用。

  3. 明确不使用延迟扩展,因为这会导致%~1%%i%LocalAppdata%%Appdata%扩展为具有一个或多个的字符串! 将感叹号解释为文字字符将不再正确处理。

  4. 字符串比较运算符==用于比较两个字符串,而不是 integer 比较运算符equ也适用于字符串,但在一些罕见的用例中与字符串比较运算符不同。 有关详细信息,请参阅Windows 批处理文件中与 NEQ、LSS、GTR 等等效的符号

  5. 传递给批处理文件的第一个参数字符串将在开头和结尾删除" ,如果两边都包含在"中,否则批处理文件处理由于严重的语法错误已经在第二行停止。 如果有人用google"之类的东西运行批处理文件,仍然会发生这种情况,即参数字符串的末尾有一个双引号,但开头没有双引号。也可以通过额外的方法来处理这个极其罕见的用例命令行,但这里不应该真的有必要,因为这是程序或用户启动批处理文件的语法错误。

  6. 命令GOTO用于避免命令块,这使得可以引用所有环境变量而不会延迟扩展。

命令FOR不支持在/R之后指定的路径内延迟扩展。 这是 DosTips 论坛主题Limitation in for /r command 中记录的此命令的一个已知问题。 解决方案是避免在/R之后指定的目录路径字符串内延迟扩展。

可以在CD之前使用(不适用于 UNC 路径)或PUSHD (也适用于启用了命令扩展的 UNC 路径)和循环之后的POPD 或者使用由另一个在后台启动的命令进程执行的命令DIR ,它的优点是还可以找到包含名称中的字符串cache的隐藏目录, for /D忽略,而for /R也遍历隐藏目录。

@echo off & setlocal EnableExtensions DisableDelayedExpansion
if /I not "%~1" == "chrome" goto SearchAppdata

for /F "delims=" %%i in ('dir "%LocalAppData%\Google\%~1\*Cache*" /AD-L /B /S 2^>nul') do echo "%%i"
goto EndBatch

:SearchAppdata
for /F "delims=" %%i in ('dir "%Appdata%\%~1\*Cache*" /AD-L /B /S 2^>nul') do echo "%%i"

:EndBatch
endlocal

在这种情况下,由于选项/AD-L (属性目录,但不是属性链接),重解析点(目录连接、符号链接)被显式忽略,有关 Windows 上的链接的更多信息,请参阅SS64 - MKLINK。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM