Windows 用于回路和测力计

Windows 用于回路和测力计,windows,for-loop,batch-file,cmd,Windows,For Loop,Batch File,Cmd,我需要一种快速的方法在bat文件中插入几行结构化数据 我使用了一个名为myarray的数组来扫描和“读取”我的值,但它不起作用,我不明白为什么 这是我的代码: @echo off set myarray[1]=myfield1#myfield2#mysubfield31;mysubfield32#myfield4 for /f "tokens=1-9 delims=#" %%a in ('echo %myarray[1]%') do ( echo field1 is %%a ec

我需要一种快速的方法在bat文件中插入几行结构化数据 我使用了一个名为myarray的数组来扫描和“读取”我的值,但它不起作用,我不明白为什么 这是我的代码:

@echo off
set myarray[1]=myfield1#myfield2#mysubfield31;mysubfield32#myfield4
for /f "tokens=1-9 delims=#" %%a in ('echo %myarray[1]%') do (
    echo field1 is %%a
    echo field2 is %%b
    echo field3 is %%c
    echo field4 is %%d
    for /f "tokens=1-9 delims=;" %%k in ('echo %%c') do (
        echo subfield3 is %%k
        echo subfield3 is %%l       
    )
)
输出如下:

field1 is myfield1
field2 is myfield2
field3 is mysubfield31 mysubfield32
field4 is myfield4
subfield3 is mysubfield31 mysubfield32
subfield3 is
为什么我不能简单地获得:

subfield3 is mysubfield31 
subfield3 is mysubfield32
其中“;”在第二个中用作delimeter for?

也就是说,分号被视为空白(不是由
for
循环处理,而是由执行
echo
命令的子shell处理)。这将导致分号替换为空格,以便
echo field3 is%%c
生成输出
field3 is mysubfield31 mysubfield32
。删除
delims=从内部循环开始,因此它使用默认的分隔符(空格和制表符),或者选择不同的分隔符字符,您的脚本应按预期工作。但是,请注意,当嵌套“数组”的字段包含空格时,依赖内部循环中的默认分隔符可能会产生不希望的结果

证明:

  • 证明根本原因:

    for /f "tokens=*" %%a in ('echo.a#b;c#d^|find ";"') do echo _%%a_
    
    输出:无(即在回显字符串中未找到分号)

    输出:
    \u a#b c#d#

    显然,这适用于所有(
    =
    ,空格和制表符),因为我可以用它们中的每一个重现这种行为

  • 带有输入字符串
    a#b;c#d

    输出:

    field1 is a
    field2 is b c
    field3 is d
    subfield3 is b c
    subfield3 is
    field1 is a
    field2 is b c
    field3 is d
    subfield3 is b
    subfield3 is c
    field1 is a
    field2 is b+c
    field3 is d
    subfield3 is b
    subfield3 is c
    输出:

    field1 is a
    field2 is b c
    field3 is d
    subfield3 is b c
    subfield3 is
    field1 is a
    field2 is b c
    field3 is d
    subfield3 is b
    subfield3 is c
    field1 is a
    field2 is b+c
    field3 is d
    subfield3 is b
    subfield3 is c
    输出:

    field1 is a
    field2 is b c
    field3 is d
    subfield3 is b c
    subfield3 is
    field1 is a
    field2 is b c
    field3 is d
    subfield3 is b
    subfield3 is c
    field1 is a
    field2 is b+c
    field3 is d
    subfield3 is b
    subfield3 is c
    dbenham提出的另一个解决方案是启用延迟扩展,并在运行时扩展变量:

    @echo off
    setlocal EnableDelayedExpansion
    set "foo=a#b;c#d"
    for /f "tokens=1-3 delims=#" %%a in ('echo !foo!') do (
      echo field1 is %%a
      echo field2 is %%b
      echo field3 is %%c
      for /f "tokens=1-2 delims=;" %%k in ('echo %%b') do (
        echo subfield3 is %%k
        echo subfield3 is %%l       
      )
    )
    
    但是,更好的解决方案是完全放弃批处理,转而使用实际支持数组的语言,例如PowerShell。

    也就是说,分号被视为空白(不是由
    for
    循环处理,而是由执行
    echo
    命令的子shell处理)。这将导致分号替换为空格,以便
    echo field3 is%%c
    生成输出
    field3 is mysubfield31 mysubfield32
    。删除
    delims=从内部循环开始,因此它使用默认的分隔符(空格和制表符),或者选择不同的分隔符字符,您的脚本应按预期工作。但是,请注意,当嵌套“数组”的字段包含空格时,依赖内部循环中的默认分隔符可能会产生不希望的结果

    for /f "tokens=1-9 delims=#" %%a in ("%myarray[1]%") do (
    
    证明:

  • 证明根本原因:

    for /f "tokens=*" %%a in ('echo.a#b;c#d^|find ";"') do echo _%%a_
    
    输出:无(即在回显字符串中未找到分号)

    输出:
    \u a#b c#d#

    显然,这适用于所有(
    =
    ,空格和制表符),因为我可以用它们中的每一个重现这种行为

  • 带有输入字符串
    a#b;c#d

    输出:

    field1 is a
    field2 is b c
    field3 is d
    subfield3 is b c
    subfield3 is
    field1 is a
    field2 is b c
    field3 is d
    subfield3 is b
    subfield3 is c
    field1 is a
    field2 is b+c
    field3 is d
    subfield3 is b
    subfield3 is c
    输出:

    field1 is a
    field2 is b c
    field3 is d
    subfield3 is b c
    subfield3 is
    field1 is a
    field2 is b c
    field3 is d
    subfield3 is b
    subfield3 is c
    field1 is a
    field2 is b+c
    field3 is d
    subfield3 is b
    subfield3 is c
    输出:

    field1 is a
    field2 is b c
    field3 is d
    subfield3 is b c
    subfield3 is
    field1 is a
    field2 is b c
    field3 is d
    subfield3 is b
    subfield3 is c
    field1 is a
    field2 is b+c
    field3 is d
    subfield3 is b
    subfield3 is c
    dbenham提出的另一个解决方案是启用延迟扩展,并在运行时扩展变量:

    @echo off
    setlocal EnableDelayedExpansion
    set "foo=a#b;c#d"
    for /f "tokens=1-3 delims=#" %%a in ('echo !foo!') do (
      echo field1 is %%a
      echo field2 is %%b
      echo field3 is %%c
      for /f "tokens=1-2 delims=;" %%k in ('echo %%b') do (
        echo subfield3 is %%k
        echo subfield3 is %%l       
      )
    )
    
    然而,更好的解决方案是完全放弃批处理,转而使用实际支持阵列的语言,例如PowerShell

    for /f "tokens=1-9 delims=#" %%a in ("%myarray[1]%") do (
    
    可能会更好一点

    可能会工作得更好一些…

    这很有效:

    @echo off
    set myarray[1]=myfield1#myfield2#mysubfield31;mysubfield32#myfield4
    for /f "tokens=1-9 delims=#" %%a in ("%myarray[1]%") do (
        echo field1 is %%a
        echo field2 is %%b
        echo field3 is %%c
        echo field4 is %%d
        for /f "tokens=1-9 delims=;" %%k in ("%%c") do (
            echo subfield3 is %%k
            echo subfield3 is %%l       
        )
    )
    pause
    
    这项工作:

    @echo off
    set myarray[1]=myfield1#myfield2#mysubfield31;mysubfield32#myfield4
    for /f "tokens=1-9 delims=#" %%a in ("%myarray[1]%") do (
        echo field1 is %%a
        echo field2 is %%b
        echo field3 is %%c
        echo field4 is %%d
        for /f "tokens=1-9 delims=;" %%k in ("%%c") do (
            echo subfield3 is %%k
            echo subfield3 is %%l       
        )
    )
    pause
    

    错了!分号被视为命令的普通分隔符(no/F选项)。在
    FOR/F
    命令中,分隔符正是放置在
    delims=…
    选项中的分隔符。在某些情况下,您认为它是分隔符是正确的,但建议将其从“delims=;”中删除作为解决方案是错误的。@AnsgarWiechers:再一次:分号在
    FOR/F
    命令中不被视为空白;链接中的文章并不是指for/F
  • 命令,而是指批处理文件参数(以及扩展名为for with NO/F选项)。有趣的是,在第二点。在您的示例中,您说“注意,当正在处理的值为
    bc
    时,嵌套的“数组”
    b;c
    现在已正确处理”!此问题与
    for
    命令的处理无关,而是与删除分号后生成
    bc
    字符串有关。从上面答案的第一行复制:“这是有文档记录的行为,分号被视为空白”。您在最后一次评论之前没有说过“已替换”(您可以在此页面中找到以确认)。当然,整个主题是关于/f
  • 命令的
    !是吗?@AnsgarWiechers-你在正确的轨道上,
    被视为空格。但您提出的仅更改分隔符的解决方案完全没有达到目的。您的“解决方案”恰好起作用,因为所有数据字段都不包含空格。但如果它们确实包含空格,则会失败。适当的解决方案可以保留
    。理想情况下,使用字符串而不是命令:
    in(“%myarray[1]”)
    。或者通过命令使用延迟扩展:
    in('echo!myarray[1]!')
    错误!分号被视为命令的普通分隔符(no/F选项)。在
    FOR/F
    命令中,分隔符正是放置在
    delims=…
    选项中的分隔符。在某些情况下,您认为它是分隔符是正确的,但建议将其从“delims=;”中删除作为解决方案是错误的。@AnsgarWiechers:再一次:分号在
    FOR/F
    命令中不被视为空白;链接中的文章并不是指for/F
    命令,而是指批处理文件参数(以及扩展名为for with NO/F选项)。有趣的是,在第二点。在您的示例中,您说“注意,当正在处理的值为
    bc
    时,嵌套的“数组”
    b;c
    现在已正确处理”!此问题与
    for
    命令的处理无关,而是与删除分号的
    bc
    字符串的生成有关。复制自上面答案中的第一行:“这是记录在案的行为,分号i