Windows 用于回路和测力计
我需要一种快速的方法在bat文件中插入几行结构化数据 我使用了一个名为myarray的数组来扫描和“读取”我的值,但它不起作用,我不明白为什么 这是我的代码: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
@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-你在正确的轨道上,在FOR/F IN()子句中处理时,代码>被视为空格。但您提出的仅更改分隔符的解决方案完全没有达到目的。您的“解决方案”恰好起作用,因为所有数据字段都不包含空格。但如果它们确实包含空格,则会失败。适当的解决方案可以保留代码>。理想情况下,使用字符串而不是命令: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