我需要快速的方法在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
其中是“;”用作第二部分中的分隔符?
答案 0 :(得分:5)
这有效:
@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
答案 1 :(得分:1)
for /f "tokens=1-9 delims=#" %%a in ("%myarray[1]%") do (
可能会更好......
答案 2 :(得分:-1)
那是documented behavior,分号被视为空格(不是for
循环,而是由子shell执行echo
命令)。这会导致分号被替换为空格,因此echo field3 is %%c
生成输出field3 is mysubfield31 mysubfield32
。从内部循环中删除delims=;
,因此它使用默认分隔符(空格和制表符),或选择不同的分隔符,并且脚本应按预期工作。但请注意,当嵌套“数组”的字段包含空格时,依赖内部循环中的默认分隔符可能会产生不希望的结果。
证明:
证明根本原因:
for /f "tokens=*" %%a in ('echo.a#b;c#d^|find ";"') do echo _%%a_
输出:无(即在回显的字符串中找不到分号)
for /f "tokens=*" %%a in ('echo.a#b;c#d^|find " "') do echo _%%a_
输出:_a#b c#d_
显然,这适用于所有delimiter characters(,
,;
,=
,空格和制表符),因为我可以为每个人重现此行为。
带有输入字符串a#b;c#d
的简化脚本:
@echo off
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
)
)
输出:
field1 is a
field2 is b c
field3 is d
subfield3 is b c
subfield3 is
注意输出中2 nd 和4 th 行中b
和c
之间的空格。
与2.相同的脚本,但从内循环中移除了delims=;
:
@echo off
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" %%k in ('echo %%b') do (
echo subfield3 is %%k
echo subfield3 is %%l
)
)
输出:
field1 is a
field2 is b c
field3 is d
subfield3 is b
subfield3 is c
请注意,嵌套的“数组”b;c
(来自变量%foo%
)现在会被处理为正确的输出(第4行和第5行)。这是因为空格和制表符是for /f
循环中的默认分隔符。
与2.相同的脚本,但使用+
作为嵌套“数组”的分隔符:
@echo off
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
)
)
输出:
field1 is a
field2 is b+c
field3 is d
subfield3 is b
subfield3 is c
请注意,2 nd 输出行不再包含虚假空间,并且再次正确处理嵌套的“数组”(第4行和第5行)。
为了完整性:更好的解决方案是完全删除echo
并简单地循环使用双引号字符串,如foxidrive和Peter Wright所示,因为它完全避免了这个问题。
@echo off
set "foo=a#b;c#d"
for /f "tokens=1-3 delims=#" %%a in ("%foo%") do (
echo field1 is %%a
echo field2 is %%b
echo field3 is %%c
for /f "tokens=1-2 delims=;" %%k in ("%%b") do (
echo subfield3 is %%k
echo subfield3 is %%l
)
)
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中。