如何使用批处理在数组(for循环)中一次处理两个元素?

时间:2016-02-01 09:51:21

标签: arrays windows batch-file

我正在尝试为传递给我脚本的参数创建某种处理程序。我们的想法是一起处理“成对”的论点。所以,也就是说1和2,3和4,5和6等等......( NOT 2和3,4和5,6和7,依此类推...... 。)

我认为批次非常酷,但我对批处理非常新。我迷失了如何做到这一点。到目前为止,我已成功将参数放入一个包含以下脚本的数组中:

SETLOCAL EnableDelayedExpansion
set /a count+=1
set "params[%count%]=%~1"
shift
if defined params[%count%] (
    goto :repeat
) else (
    set /a count-=1
)

现在我只需要成对处理每个元素。我根本不知道怎么做。我知道如何使用for /F "tokens=2 delims==" %%s in ('set params[') do单独处理元素,但我不知道怎么做对

旁边有人可以解释延迟扩展应该做什么吗?

只是为了清晰,通过“句柄”我的意思是操纵它并将其作为参数传递到另一个脚本。这必须成对完成。

2 个答案:

答案 0 :(得分:2)

@ECHO Off
SETLOCAL ENABLEDELAYEDEXPANSION
:: remove variables starting $ or #
For %%b IN ($ #) DO FOR  /F "delims==" %%a In ('set %%b 2^>Nul') DO SET "%%a="

SET /a count=0
SET "select=this is select's original value"

ECHO parameters received = %*

:loop
REM SET $... and #... to the parameter-pair.
SET $%count%=%1
SET #%count%=%2
IF NOT DEFINED $%count% GOTO process
IF NOT DEFINED #%count% ECHO "Incomplete pair"&GOTO :EOF
SET /a count +=1
:: shift twice to move 2 parameters
shift&shift&GOTO loop

:process
ECHO %count% pairs found
SET $
SET #

FOR /L %%a IN (1,1,%count%) DO (
 REM note that this changes "select"
 SET /a select=%%a - 1
 CALL SET /a item1=%%$!select!%%
 CALL SET /a item2=%%#!select!%%

 ECHO pair %%a is !item1! and !item2! from $!select! and #!select! NOT $#%select%
)

ECHO ----------------- select = %select% ----------
SET /a count-=1

FOR /L %%a IN (0,1,%count%) DO (
 REM note that this changes "select"
 SET /a select=%%a + 1

 ECHO pair !select! is !$%%a! and !#%%a! from $%%a and #%%a NOT $#%select%

GOTO :EOF

首先,设置一些初始值。第一个for可确保清除任何以$#开头的变量。

$0#0设置为第一个和第二个参数。如果没有设置$ 0,那么我们没有其他数据,所以处理我们拥有的数据。如果设置了$ 0但#0不是,我们没有一对抱怨并终止。

如果同时设置了#0 ans $ 0,则将参数递增countshift两次,然后绕循环运行。下一对将放在$ /#1中,依此类推,直到参数耗尽。

现在显示参数计数以及已设置的$#值。

Next循环显示对变量的不必要操作。

  • 首先将select设置为比循环计数器少1个。
  • 然后使用解析技巧获取$ [select的当前值]的值。该行转换为“SET / a item1 =%$ n%”,其中nselect运行时值 - 即。通过循环改变的值。
  • 然后显示结果。 item1在块(带括号的系列语句)中发生了更改,因此我们需要!item1来访问更改后的值 - %item1%会给出循环为{{1时的值' }}。您可以在同一行的parsed报告中看到该内容。

最后一个循环是相同的想法 - 但是将%% a从0改为(count-1)。请注意,虚线select行中的select具有在上一循环中分配的最后一个值。

因此,我们再次在块中更改echo,因此我们发现select!select!之间存在差异。我们还可以使用%select%直接访问$0 - 这是变量[!$%%a!的当前值,其中包含循环控件$的当前值]

答案 1 :(得分:0)

@echo off
setlocal EnableDelayedExpansion

rem Store arguments one by one
set "count=0"
:repeat
   set /A count+=1
   set "param[%count%]=%~1"
   shift
if "%~1" neq "" goto repeat

rem Show arguments in pairs
set /A countMIN1=count-1
for /L %%i in (1,2,%countMIN1%) do (
   set /A j=%%i+1
   for %%j in (!j!) do echo !param[%%i]! !param[%%j]!
)

有关详细信息,请参阅:Arrays, linked lists and other data structures in cmd.exe (batch) script