Arrays 从批处理文件中的数组中删除元素

Arrays 从批处理文件中的数组中删除元素,arrays,batch-file,Arrays,Batch File,我在一个批处理文件中有一个数组,其中包含几个文件目录。我想删除数组的前三个元素,并让所有元素都转换(即第四个元素取代第一个,第五个元素取代第二个,第六个元素取代第三个,等等)。这是可以在批处理脚本中完成的吗 例如: [directoryA, directoryB, directoryC, directoryD, directoryE, directoryF] 更改为: [directoryD, directoryE, directoryF] 下面是我为“数组”编写的代码: 我能想到的最好的方

我在一个批处理文件中有一个数组,其中包含几个文件目录。我想删除数组的前三个元素,并让所有元素都转换(即第四个元素取代第一个,第五个元素取代第二个,第六个元素取代第三个,等等)。这是可以在批处理脚本中完成的吗

例如:

[directoryA, directoryB, directoryC, directoryD, directoryE, directoryF]
更改为:

[directoryD, directoryE, directoryF]
下面是我为“数组”编写的代码:


我能想到的最好的方法是使用两个“数组”,一个用于数据,另一个用于数据当前是否有效。下面的示例代码创建一个包含任何命令行参数的
dir
“array”和另一个
valid
“array”,然后仅从
dirs
打印“valid”数据

valid[i]
将等于
1
当且仅当
dirs[i]
中的数据有效时。
valid[i]
中的任何其他值将指示忽略
dirs[i]
中的数据

@echo off
setlocal enabledelayedexpansion

set paramCount=0
for %%x in (%*) do (
  echo %%x
  set /A paramCount+=1

  REM Add data to dirs array
  set "dirs[!paramCount!]=%%x"

  REM Add valid flag to valid array
  set "valid[!paramCount!]=1"
)

echo Printing...

REM Delete element at index 2
set valid[2]=0

REM Print the modified array
for /L %%a in (1 1 %paramCount%) do (
  IF !valid[%%a]!==1 (echo !dirs[%%a]!)
)
示例输出:

$>deletetest.bat 1 2 3 4
1
2
3
4
Printing...
1
3
4

对不起。我想就这个话题发表一些看法

您尚未指明“阵列”的来源。您可以将其存储在变量中,例如:

set dirs=directoryA directoryB directoryC directoryD directoryE directoryF
set paramCount=0
for %%x in (%*) do (
   set /A paramCount+=1
   set "dirs[!paramCount!]=%%x"
)
但是,这不是一个数组,而是一个列表。您可以通过以下方式从子例程的参数创建此列表:

set dirs=%*
for /F "tokens=3*" %%a in ("%dirs%") do set dirs=%%b
for /L %%i in (4,1,%paramCount%) do (
   set /A j=%%i-3
   set dirs[!j!]=!dirs[%%i]!
)
set /A paramCount-=3
如果要从此列表中删除前三个元素,可以通过以下方式执行此操作:

set dirs=%*
for /F "tokens=3*" %%a in ("%dirs%") do set dirs=%%b
for /L %%i in (4,1,%paramCount%) do (
   set /A j=%%i-3
   set dirs[!j!]=!dirs[%%i]!
)
set /A paramCount-=3

另一种可能性是目录作为参数列表传递给子例程:

我认为这是基于你的例子的情况。在这种情况下,很容易通过三个
shift
命令“删除”前三个参数:

:subroutine
rem Remove first three parameters:
shift
shift
shift
rem Process the rest of parameters:
:nextParam
   if "%1" equ "" goto endParams
   echo Next param is: %1
   shift
goto nextParam
:endParams

但是,如果您有一个“实”数组(带有从1开始的数字下标),也可以通过以下方式从子例程的参数列表中创建该数组(如示例中所示):

然后,您可以通过以下方式删除前三个元素:

set dirs=%*
for /F "tokens=3*" %%a in ("%dirs%") do set dirs=%%b
for /L %%i in (4,1,%paramCount%) do (
   set /A j=%%i-3
   set dirs[!j!]=!dirs[%%i]!
)
set /A paramCount-=3

这是哪个批处理脚本shell?DOS/WINDOWS?噢,对不起--忘了提那个。我正在写一个基本的Windows.bat文件。我只是从批处理脚本开始,所以我不确定这是否是您要寻找的答案。请给我们一些您已有的代码示例,我们可以提供更好的建议。您的数组是存储在带有逗号分隔符的单个变量中,还是存储在多个变量中?directorynames是否包含引号或非字母数字字符?我不确定是否有人关注答案上的注释,但我想指出的是,我最终设置了不希望为null的元素,然后使用for循环将所有非null值添加到第二个数组中。这似乎奏效了。谢谢大家!非常有趣的想法。我没有想过那样做。我最后做的是将前三个元素设置为null,然后使用for循环创建另一个“数组”。for循环将遍历dir,检查其值是否为null,如果不是,则将其添加到新的“数组”。然后我使用新数组作为参考。谢谢大家的帮助!我也遇到过同样的方法,但它比上面的方法(需要在任何修改后完全重建数组)更详细,而上面的解决方案允许您随时选择性地重建。这一点非常好。现在我只是想让它工作,最终我会做微调和清理。到时候我可能会换掉更详细的代码段,你帮了我很大的忙。我会用这个作为公认的答案,稍后可能会实施。这篇文章内容丰富,谢谢。我应该再往回走一点。我正在从java程序调用这个批处理文件。我使用Java API为Runtime.getRuntime().exec()方法提供的“commands[]”数组传入大量字符串作为参数。每个目录都作为参数传入。然后,我访问这些参数,并使用它们设置局部变量,稍后我可以在脚本中对其进行操作。我希望这能澄清一些事情。