批处理文件:使用嵌套循环中的列表元素

问题描述 投票:0回答:1

我一直在努力让批处理脚本工作,看起来我需要问一些在Batch中有更多专业知识的人,因为我没有任何线索,为什么它一直无法正常工作。我的目的是得到VAR列表的两个元素被交换:

    @echo off

    rem enable delayed expansion, required for extended usage of environment variables
    SETLOCAL EnableDelayedExpansion
    SETLOCAL EnableExtensions

    set VAR=abcd efgh ijkl mnopq rstvw qwert yxcva rtzewrw yxvys
    set fst=qwert
    set scnd=rstvw

    call :test %VAR%

    :test
    SETLOCAL

    for %%i in (%*) do (
        for %%j in (%* %%i) do (
            if %scnd% equ %%i (
                if %fst% equ %%j (
                echo "gotcha before swapping: " "i: " %%i "j: " %%j
                    set tempor=%%i
                    set i=%%j
                    set j=!tempor!
                    echo "gotcha after swapping: " "i: " !i! "j: " !j!          
                    set List=!List! %%j %%i
                )
            )
        )
        set List=!List! %%i
        echo "List: " !List!
    )

    ENDLOCAL
    goto :eof

    :ende

我想让List看起来像这样:

abcd efgh ijkl mnopq qwert rstvw yxcva rtzewrw yxvys 

其中fst(对于第一个元素)和scnd(第二个元素)被交换。

输出是这样的:"List: " abcd efgh ijkl mnopq qwert rstvw rstvw qwert yxcva rtzewrw yxvys,所以我得到了qwertrstvw的双重输入,我知道这是因为set List=!List! %%i的位置。

至少我知道,交换工作正常。但我的问题是:如果我把它放在else分支中,正如我通常用其他任何脚本语言做的那样,List将在每个循环中用%%i%%j填充,所以它变得无用......

list batch-file nested-loops
1个回答
0
投票

你的问题似乎是%%i%i%是完全不同的变量。您无法为%%i分配值 - 只有for命令可以。

您似乎正在尝试执行插入排序以构建排序的字符串列表。您的代码结构可能是编辑的遗留问题,但是在发布时,例程将通过流程重新输入。此外,由于例程:test包含在setlocal / endlocal括号中,因此在list例程之外将不会看到对:test的更改。并且连续有两个setlocal命令建立了两个嵌套的本地环境。可以在一个setlocal语句中同时指定这两个选项。请注意,setlocal不是一个开关 - 它建立了一个本地环境(是的,微软已经被要求建立delayed expansion等作为单独的swtich类型的操作,如echo on/off

另请注意,生成的列表包含前导空格。我用以下替代例程遵循了这个想法:

雷姆

SET "list2="
for %%i in (%*) do (
 REM %%i has each element in turn
 SET "startlist= "
 SET "endlist= "
 IF defined list2 for %%j in (!list2!) do (
  IF "%%j" lss "%%i" (
   SET "startlist=!startlist!%%j "
  ) ELSE (
   SET "endlist=!endlist!%%j "
  )
 )
 SET "list2=!startlist!%%i!endlist:~0,-1!"
)
ECHO "List2:" %list2%+

(我添加了一个+到最后,以显示字符串list2的结束。


是 - 在原始问题中指定所需的输出可以轻松解决问题

:test
SETLOCAL
SET "List="
for %%i in (%*) do (
 if %fst% equ %%i ( SET "List=!List! %scnd%"
 ) ELSE (
  if %scnd% equ %%i ( SET "List=!List! %fst%"
  ) ELSE set List=!List! %%i
 )
 echo "List: " !List!
)
ENDLOCAL
goto :eof

我假设缺乏信息,否则保证fstscnd都保证在输入中只出现一次。

© www.soinside.com 2019 - 2024. All rights reserved.