%variable%
是环境变量。它们使用 or 设置set
并且可以使用%foo%
or访问!foo!
(如果启用,则延迟扩展)。%%a
是由for
命令创建的特殊变量,用于表示当前循环项或当前行的标记。
for
可能是批处理文件中最复杂和最强大的部分。如果您需要循环,那么在大多数情况下for
,您已经涵盖了。help for
有总结。
你可以
- 遍历文件:
for %x in (*.txt) do ...
- 重复某件事n次:(
for /l %x in (1, 1, 15) do...
参数是start,step和end)
- 迭代一组值:
for %x in (a, b, c) do ...
- 遍历文件的行:
for /f %x in (foo.txt) do ...
- 标记文件的行:
for /f "tokens=2,3* delims=," %x in (foo.txt) do ...
- 遍历命令的输出:
for /f %x in ('somecommand.exe') do ...
这只是一个简短的概述。它变得更加复杂,但请阅读帮助。
形式的变量%%a
(或者%a
如果for
在批处理文件之外使用)与批处理文件和子例程(%1
, %2
, ...)的参数非常相似。可以对它们应用某些类型的扩展,例如,如果变量表示带有您可以使用的路径的文件名,则仅获取文件名和扩展名%%~nxa
。中给出了这些的完整概述help for
。
另一方面,环境变量还有其他一些特殊的东西。您可以通过%foo:a=b%
会在其中执行替换,%foo%
除了 everya
被替换为b
. 您也可以使用子字符串:%foo:~4,2%
. 这些东西的描述可以在 中找到help set
。
至于为什么%variables%
和%%a
是不同的事情,有点难以回答,可能只是历史上的怪事。如上所述,我猜还有第三种变量%1
等,它们与 中使用的变量非常相似,for
并且已经存在了更长的时间。由于环境变量由于块而使用起来有点笨拙for
,因此严重依赖延迟扩展,因此可能决定使用与参数相同的机制而不是环境变量。
此外,环境变量可能更昂贵,因为该进程有一个特殊的“环境”内存块,它们variable=value␀
成对存储,因此更新环境变量可能涉及复制一些内存,而其他类型的变量可能更轻量级. 不过,这是猜测。
至于您的问题,您实际上并不需要for
:
find /v ":" "%appdata%\gamelauncher\options.txt" | find "menu=a" && set usemenu=a
这只会set
在前面的命令成功(即menu=a
找到)时运行。这应该比for
. 根据我读到的内容,您正在尝试查看是否menu=a
存在于不包含冒号的行中,在这种情况下usemenu
应设置为a
,对吗?(同样 forb
和c
。您可以尝试for
通过循环文件或输出的行并适当地标记化以找出 的值,menu
但根据行的格式,这可能会很棘手。如果你有什么理论上可行,那么你应该坚持下去。但是,您可以在它周围使用一个循环以避免不得不重复同一行三次a
,b
并且c
:
for %%X in (a b c) do (
find /v ":" "%appdata%\gamelauncher\options.txt" | find "menu=%%X" && set usemenu=%%X
)
If the file you are parsing is simple, however, with just name=value
pairs in each line where : foo
would be a comment, then you could use for
as well:
for /f "tokens=1,* eol=: delims==" %%A in (%appdata%\gamelauncher\options.txt) do (
if "%%A"=="menu" set usemenu=%%B
)
But that depends a little on the exact format of the file. Above snippet would now read the file line by line and for each line would discard everything after a colon (the eol=:
option), use the equals sign as a token delimiter and capture two tokens: The part before the first =
and everything after it. The tokens are named starting with %%A
so the second one is implicitly %%B
(again, this is explained in help for
). Now, for each line we examine the first token and look whether it's menu
and if so, assign its value to the usemenu
variable. If you have a lot of possible options to support this is certainly easier to maintain :-).