有什么区别:%% a和%变量%变量?

时间:2013-03-15 09:29:15

标签: variables batch-file cmd

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的值?

提前感谢您的帮助!

1 个答案:

答案 0 :(得分:36)

%variable% environment 变量。它们设置为set,可以使用%foo%!foo!进行访问(如果启用则会延迟展开)。 %%a是由for命令创建的特殊变量,用于表示当前循环项或当前行的标记。

for可能是批处理文件中最复杂和最强大的部分。如果您需要循环,那么在大多数情况下for可以覆盖您。 help for有摘要。

你可以

  • 遍历文件:for %x in (*.txt) do ...
  • 重复某些 n 次: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,对吧? (同样适用于ab。您可以尝试通过循环文件或输出的行来哄骗c来做到这一点,然后适当地进行标记以找出{{1}的值但是根据线条的格式,这可能会很棘手。如果你有什么在理论上有效,那么你应该坚持下去。但是你可以在它周围使用一个循环来避免重复同一条线三次formenua

b

如果您要解析的文件很简单,但每行只有cfor %%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变量。如果你有很多可能的选择来支持这一点肯定更容易维护: - )。