2013-03-15 333 views
9
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”。区别:%% a和%variable%变量之间的区别是什么?

首先,%变量%和%% a之间有什么区别?

其次,有人可以向我解释'for'命令吗?我有谷歌它的方式太多,所有的解释似乎很复杂...

我想要做的是从options.txt拉一个变量,所以我可以改变我的游戏启动器的菜单样式。有3种样式(a,b和c),所以如果options.txt显示“menu = a”,我怎样才能让它设置一个像%usemenu%这样的变量值?

感谢您提前提供任何帮助!

回答

27

%variable%环境变量。它们设置为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%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,对不对? (对于bc也是如此,你可以尝试通过循环遍历文件或输出的行并使用适当的标记来确定menu的值,但根据行的格式,这可能会非常棘手,请尝试使用for。你必须在理论上有工作是什么,那么你应该简单地坚持这一点但是,您可以使用它周围的循环,以避免重复在同一行三次abc

for %%X in (a b c) do (
    find /v ":" "%appdata%\gamelauncher\options.txt" | find "menu=%%X" && set usemenu=%%X 
) 

如果文件你解析很简单,但是,只有name=value对在每一行: foo将是一个评论,那么你可以使用for还有:

for /f "tokens=1,* eol=: delims==" %%A in (%appdata%\gamelauncher\options.txt) do (
    if "%%A"=="menu" set usemenu=%%B 
) 

但是,这取决于文件的具体格式一点。上面的片段现在将逐行读取文件,并且每行将放弃冒号(eol=:选项)后的所有内容,使用等号作为令牌分隔符并捕获两个令牌:第一个=之前的部分及其后的所有内容。令牌的名称以%%A开头,所以第二个隐含地为%%B(同样,这在help for中进行了说明)。现在,对于每一行,我们检查第一个标记并查看它是否为menu,如果是,则将其值分配给usemenu变量。如果你有很多可能的选择来支持,这当然更容易维护:-)。

+0

那么我如何使用这个来解决我的游戏启动器问题?我是否正确使用该命令? – magicbennie 2013-03-15 09:50:32

+1

你在那里:) – Joey 2013-03-15 10:25:47

相关问题