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

mag*_*nie 12 variables cmd batch-file

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 )
Run Code Online (Sandbox Code Playgroud)

是的,在这段代码中(可能不起作用,我想要找到的)我们在'for'命令中有这个"%% a".

首先,%variable%和%% a之间的区别是什么?

第二,有人可以向我解释'for'命令吗?谷歌太过分了,所有的解释似乎都很复杂......

我想要做的是从options.txt中提取变量,这样我就可以更改游戏启动器的菜单样式.有3种样式(a,b和c),所以如果options.txt读取"menu = a",我如何才能将它设置为像%usemenu%这样的变量?

在此先感谢您的帮助!

Joe*_*oey 37

%variable%是环境变量.它们设置为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 ...
  • tokenize文件的行: 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
Run Code Online (Sandbox Code Playgroud)

这将仅set在前面的命令成功(即menu=a找到)时运行.这应该比相当容易for.从我读到的,你试图看看是否menu=a存在一个不包含冒号的行,在这种情况下usemenu应该设置为a,对吗?(同样适用于b和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
)
Run Code Online (Sandbox Code Playgroud)

如果您正在解析的文件很简单,只需name=value在每行中成对: foo注释,那么您也可以使用for:

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

但这取决于文件的确切格式.上面的片段现在会逐行读取文件,并且每行都会丢弃冒号后的所有内容(eol=:选项),使用等号作为标记分隔符并捕获两个标记:第一个之前的部分=和之后的所有内容.标记以起始命名,%%A因此第二个标记是隐含的%%B(同样,这将在中解释help for).现在,对于每一行,我们检查第一个标记并查看它是否是menu,如果是,则将其值usemenu赋给变量.如果你有很多可能的选择来支持这肯定更容易维护:-).