如何为文件中的每个搜索结果设置不同的变量?

时间:2019-04-20 12:00:42

标签: batch-file command-prompt

这是我以前的问题的附加内容:

How to search for line with Effective("flyer", 100%); in a file and get the number assigned to a variable?

到目前为止,我的代码是:

@echo off
set "Effective="
for /F "tokens=2 delims=%%) " %%I in ('%SystemRoot%\System32\find.exe /I "flyer" file.cfg') do set "Effective=%%I"
if defined Effective echo The effective value is: %Effective%

此代码从100行中提取数字Effective("flyer", 100%);file.cfg中。

但是如果flyer中的file.cfg有两行怎么办?

我已经尝试过了,此代码采用了最后一个传单值50

Effective("flyer", 100%);

Effective("flyer", 50%);

如何在它们之间进行选择?

包含第一个传单的第一个代码块是:

CreateWeaponType("jda.weapon.aatower")
{
  Style("Projectile");

  MaxRange(96);

  HorizAngle(90);
  HorizSeparation(180);
  VertAngle(0);
  VertSeparation(120);
  TurnRate(90);
  Speed(100);
  Fixed(1);


  Damage()
  {
    Amount(10);

    Effective("infantry", 0%);
    Effective("vehicle", 0%);
    Effective("structure", 0%);
    Effective("flyer", 100%);

    Effective("mine", 0%);
  }

  Projectile("jda.proj.aatower");
  Delay(1);
  FirePoints()
  {
    Add("HP-Fire1");
    Add("HP-Fire2");
    Add("HP-Fire3");
    Add("HP-Fire4");
  }
}

第二张传单在:

CreateObjectType("jda.exp.aatower", "Explosion")
{
  MapObj()
  {
    Mesh();
    GenericFX()
    {
      Add("ExplosionObj::Explode", "jda.fx.aatower.exp");
    }
  }
  ExplosionObj()
  {
    Damage()
    {
      Amount(16);

      Effective("infantry", 0%);
      Effective("vehicle", 0%);
      Effective("structure", 0%);
      Effective("flyer", 50%);
      Effective("mine", 0%);
    }
    AreaInner(4);
    AreaOuter(4);
    Persist(0);
  }
}

如何为每个变量设置不同的变量?

3 个答案:

答案 0 :(得分:2)

@echo off
setlocal enabledelayedexpansion
set /a count=0
for /F "tokens=2 delims=%%) " %%I in ('%SystemRoot%\System32\find.exe /I "flyer"^<file.cfg') do set /a count+=1&set "Effective[!count!]=%%I"
echo %count% items found
if %count% gtr 0 set effective[

此处的关键行是setlocal enabledelayedexpansion行,该行调用delayed expansion,其中语法!var!导致var的值,因为它可能在{{1} }循环。

因此,forcount开始,应检测到适当的行,然后递增0,然后设置有效的[计数值]设置为适当的值。

count循环结束后,显示计数(显然,此行是可选的)。

最后一个for只会在环境中显示以set开头的值set的值-但前提是effective[大于0。

(未经测试)

答案 1 :(得分:2)

这是一个例子:

@For /F "Tokens=1*" %%A In ('FindStr /I "Effective(\"flyer\"," "file.cfg"^|Find /V /N ""')Do @For /F "Tokens=2Delims=,%% " %%C In ("%%B")Do @Set "flyer%%A=%%C"
@Set flyer[
@Pause

包括下面两行只是为了向您显示变量及其各自的值字符串。

您还可以将顶部的长行分成三行,以保持合理的行长以提高可读性:

@For /F "Tokens=1*" %%A In ('FindStr /I "Effective(\"flyer\"," "file.cfg"^
 ^|Find /V /N ""')Do @For /F "Tokens=2Delims=,%% " %%C In ("%%B"
)Do @Set "flyer%%A=%%C")
@Set flyer[
@Pause

请注意,此答案无法确定.cfg文件的哪个特定部分属于哪个百分比:

答案 2 :(得分:1)

MagooCompo发布的答案已经是不错的解决方案。因此,除了您只对第一个flyer值感兴趣之外,我没有其他贡献。在这种情况下,在将flyer的第一个file.cfg编号分配给环境变量Effective之后,可以使用原始代码的少量修改来退出循环,并跳转到循环下面的标签。

@echo off
set "Effective="
for /F "skip=2 tokens=2 delims=%%) " %%I in ('%SystemRoot%\System32\find.exe /I "flyer" file.cfg') do set "Effective=%%I" & goto HaveValue
:HaveValue
if defined Effective echo The effective value is: %Effective%

find.exe输出空行,而行---------- FILE.CFG使用 FOR 选项skip=2跳过前两行以避免分配的原因FILE.CFG到环境变量Effective

当然也可以只对第一个flyer值感兴趣而重写整个代码。

@echo off
for /F "tokens=2 delims=%%) " %%I in ('%SystemRoot%\System32\findstr.exe /R /I "effective.*flyer" file.cfg') do set "Effective=%%I" & goto HaveValue
echo No line with "flyer" found in "file.cfg"
goto :EOF

:HaveValue
echo The effective value is: %Effective%

此代码使用findstr.exe代替不输出标题行的find.exe。现在,使用了一个非常简单的正则表达式搜索字符串,而不仅仅是文字搜索字符串flyer

但是 Magoo Compo 提供的批处理文件已经很好,因为它们对两个flyer编号都非常感兴趣。