for /f "tokens=*" %%a in ('find /v ":" "%appdata%\gamelauncher\options.txt" ^| find "menu=a"') do ( set usemenu=a )
for /f "tokens=*" %%a in ('find /v ":" "%appdata%\gamelauncher\options.txt" ^| find "menu=b"') do ( set usemenu=b )
for /f "tokens=*" %%a in ('find /v ":" "%appdata%\gamelauncher\options.txt" ^| find "menu=c"') do ( set usemenu=c )
是的,在这段代码中(可能不起作用,我想要找到的)我们在'for'命令中有这个“%% a”。
首先,%variable%和%% a?
之间的区别是什么?第二,有人可以向我解释'for'命令吗?我已经谷歌太多了,所有的解释似乎都很复杂......
我要做的是从options.txt中提取变量,这样我就可以更改游戏启动器的菜单样式。有3种样式(a,b和c),所以如果options.txt读取“menu = a”,我如何才能将%usemenu%变量设置为a的值?
提前感谢您的帮助!
答案 0 :(得分:36)
%variable%
是 environment 变量。它们设置为set
,可以使用%foo%
或!foo!
进行访问(如果启用则会延迟展开)。 %%a
是由for
命令创建的特殊变量,用于表示当前循环项或当前行的标记。
for
可能是批处理文件中最复杂和最强大的部分。如果您需要循环,那么在大多数情况下for
可以覆盖您。 help for
有摘要。
你可以
for %x in (*.txt) do ...
for /l %x in (1, 1, 15) do...
(参数为开始,步骤和结束 )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
,{ {1}},...)。可以对它们应用某些类型的扩展,例如,如果变量表示带有可以使用%2
的路径的文件名,则只获取文件名和扩展名。 %%~nxa
中提供了完整的概述。
另一方面,环境变量还有其他特殊的东西。您可以通过help for
在%foo:a=b%
中执行替换,但每个%foo%
都会被a
替换。您也可以使用子字符串: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
和b
。您可以尝试通过循环文件或输出的行来哄骗c
来做到这一点,然后适当地进行标记以找出{{1}的值但是根据线条的格式,这可能会很棘手。如果你有什么在理论上有效,那么你应该坚持下去。但是你可以在它周围使用一个循环来避免重复同一条线三次for
,menu
和a
:
b
如果您要解析的文件很简单,但每行只有c
对for %%X in (a b c) do (
find /v ":" "%appdata%\gamelauncher\options.txt" | find "menu=%%X" && set usemenu=%%X
)
将成为评论,那么您可以使用{{1同样:
name=value
但这取决于文件的确切格式。上面的代码片段现在会逐行读取文件,并且每行都会丢弃冒号后的所有内容(: foo
选项),使用等号作为标记分隔符并捕获两个标记:第一个{{1}之前的部分1}}以及之后的一切。标记以for
开头,因此第二个标记隐含for /f "tokens=1,* eol=: delims==" %%A in (%appdata%\gamelauncher\options.txt) do (
if "%%A"=="menu" set usemenu=%%B
)
(同样,这在eol=:
中有解释)。现在,对于每一行,我们检查第一个标记并查看它是否为=
,如果是,则将其值分配给%%A
变量。如果你有很多可能的选择来支持这一点肯定更容易维护: - )。