在批处理文件中以恒定索引访问数组元素

时间:2018-07-07 16:42:09

标签: arrays batch-file

  

我在标题中提到了常量索引,因为StackOverflow中与批处理文件中的数组索引有关的所有问题都集中在循环内使用变量索引访问数组。

我是批处理脚本的新手。如果数组初始化为列表(在一行中)而不是每个元素单独初始化,我想用常数索引打印数组值。我编写了一个代码段,可以在其中打印arr的值,但不能打印list的值。

@echo off
set arr[0]=1
set arr[1]=2
set arr[2]=3
set list=1 2 3 4
REM Result is 2
echo %arr[1]%
REM Won't print
echo %list[1]%

3 个答案:

答案 0 :(得分:0)

字符串列表不是数组,this answer两天前展示了如何将字符串列表转换为数组。

要使数组索引为零,请使用此更改的版本

:: SO_51225079.cmd
@echo off & Setlocal EnableDelayedExpansion
set arr[0]=1
set arr[1]=2
set arr[2]=3
set i=-1&set "list= 1 2 3 4"
Set "list=%list: ="&Set /a i+=1&Set "list[!i!]=%"
set list

REM Result is 2
echo %arr[1]%
REM Won't print
echo %list[1]%

示例输出:

> SO_51225079.cmd
list[0]=1
list[1]=2
list[2]=3
list[3]=4
2
2

答案 1 :(得分:0)

您可能会混淆Batch和PowerShell。在PowerShell中,可以,您可以在一行上初始化一个数组:

$list = 1, 2, 3, 4
$list[1]
# output here would be 2

在批处理脚本语言中,没有数组对象。您可以通过具有相似或顺序命名的标量变量来模拟数组,但是Batch语言不提供诸如split()splice()push()之类的方法。

通常在批处理中,通过使用for循环进行标记化来在空格(或逗号或分号)上分割字符串。

@echo off & setlocal

rem // Quoting "varname=val" is the safest way to set a scalar variable
set "list=1 2 3 4"

rem // When performing arithmetic using "set /a", spacing is more flexible.
set /a ubound = -1

rem // Split %list% by tokenizing using a for loop
for %%I in (%list%) do (
    set /a ubound += 1

    rem // Use "call set... %%ubound%%" to avoid evaluating %ubound% prematurely.
    rem // Otherwise, %ubound% is expanded when the for loop is reached and keeps the
    rem // same value on every loop iteration.
    call set "arr[%%ubound%%]=%%~I"
)

rem // output results
set arr[

setlocal enabledelayedexpansion
rem // You can also loop from 0..%ubound% using for /L
for /L %%I in (0, 1, %ubound%) do echo Element %%I: !arr[%%I]!
endlocal

作为一个补充说明,在该代码块中,我演示了两种延迟批处理中变量扩展的方法-使用call setsetlocal enabledelayedexpansion在需要延迟检索的地方使用感叹号。有时候,了解两者都很有用。 enabledelayedexpansion方法通常更易读/更易于维护,但是在某些情况下,可能会掩盖可能存在感叹号的值(例如文件名)。因此,我尽量避免对整个脚本启用延迟扩展。


LotPings' answer很聪明,但应用范围有限。它的工作方式是使用substring substitutionlist的值设置并评估为一串命令(用&分隔)。不幸的是,它在此过程中破坏了%list%的值,并且无法处理包含空格或感叹号的值。

@echo off & setlocal

set "list="The quick brown" "fox jumps over" "the lazy dog!!!""
set /a ubound = -1

for %%I in (%list%) do (
    set /a ubound += 1
    call set "arr[%%ubound%%]=%%~I"
)

rem // output results
set arr[

for拆分方法将正确维护带引号的空格。

答案 2 :(得分:0)

批处理只有一种类型的变量:字符串。

数组和列表是非常不同的东西(并且讨论了它们,即使它们甚至存在于批处理中,但它们可以被模拟)。在批处理中,列表不是不同的元素,而只是一个字符串,数组不是单个结构,而是不同的独立变量。

不过,您可以使用for循环通过定界符(空格是默认的delimter)来分隔字符串(看起来像列表):

set list=a b c d
set element=2
for /f "tokens=%element%" %%a in ("%list%") do echo %%a

(注意:这是批处理语法。要直接在命令行上使用,请将每个%%a替换为%a