我看了很多例子,但找不到解决方案。
这个想法是找到一个扩展名为“.abc”的文件,然后将该文件名作为参数传递给 exe。 .bat文件的内容:
for /r "%CD%" %%a in (*.abc) do set p1=%%~dpnxa
@ConvertABCFile.exe %p1
评论:
for /r "%CD%" %%a in (*.coverage) do set p1=%%~dpnxa
工作正常,但第2行中没有任何内容作为参数传递。
代码中的错误是使用
%p1
而不是 %p1%
来引用 环境变量 p1
的值。
但更好的是命令行:
@for /R %%I in (*.abc) do @ConvertABCFile.exe "%%I"
如果根本不需要修改该字符串值,则永远不应将循环变量的值分配给环境变量。
选项
/R
之后的基本目录路径是可选的,并且可以在批处理文件执行的当前目录上省略,应该是递归搜索与通配符模式匹配的非隐藏文件的基本目录*.abc
。
由于选项
I
,找到的文件的文件名被一个接一个地分配为完整限定文件名(驱动器+路径+名称+扩展名)到循环变量/R
。分配给循环变量 I
的文件名始终没有包围 "
,即使在完全限定文件名中的某处包含空格或这些字符之一 &()[]{}^=;!'+,`~
,这需要将文件名参数字符串括在双引号中才能获得所有这些字符都被解释为文字字符。
当前目录通常与批处理文件目录不同。下面的命令行在批处理文件目录及其所有子目录中搜索
*.abc
文件,与执行批处理文件时的当前目录无关。
@for /R "%~dp0" %%I in (*.abc) do @ConvertABCFile.exe "%%I"
上面发布的命令行在
ConvertABCFile.exe
修改找到的 *.abc
文件的情况下并不安全。在这种情况下,有必要先将文件名列表加载到内存中,然后再 FOR 迭代它们。这可以通过来实现
@for /F "delims=" %%I in ('dir *.abc /A-D-H /B /S 2^>nul') do @ConvertABCFile.exe "%%I"
或与
@for /F "delims=" %%I in ('dir "%~dp0*.abc" /A-D-H /B /S 2^>nul') do @ConvertABCFile.exe "%%I"
用
%~dp0
引用的批处理文件的完整路径(参数 0 的驱动器和路径始终是完整的批处理文件路径)始终以反斜杠结尾,因此在将批处理文件路径与另一个批处理文件路径连接时不应使用额外的反斜杠字符串,例如文件/文件夹名称或通配符模式。
要了解所使用的命令及其工作原理,请打开命令提示符窗口,执行以下命令,并完整、仔细地阅读每个命令显示的帮助页面。
call /?
...解释了如何像使用 %~dp0
那样引用批处理文件参数。dir /?
for /?
set /?
阅读有关 使用命令重定向运算符的 Microsoft 文档,了解
2>nul
的说明。重定向运算符 >
必须在 FOR命令行上使用脱字符号
^
进行转义,以便在 Windows 命令解释器在执行命令 FOR(执行嵌入的 dir
命令行)之前处理此命令行时将其解释为文字字符使用在后台启动的单独命令进程,并使用 %ComSpec% /c
和附加的 dir
命令行作为附加参数,其中 2^>nul
已经是 2>nul
。