2017-12-27 422 views
0

我一直在试图获得批处理脚本的工作,看起来像我需要问一个在批处理方面有更多专业知识的人,因为我没有任何线索,为什么它保留不工作。我的目的是获取列表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 

我试图让列表看起来像这样:

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分支,因为我通常会在任何其他的脚本语言来做,列表将充满在每个循环%%i%%j,所以就显得无用武之地....

+0

如果你把一个if-else分支/子句中的big for循环(不管它叫什么),它应该仍然有效。 – Poypoyan

+0

你的意思是由'if%scnd%neq %% i'和'if%fst%neq %% j' ?,'%% i'和'%% j'在这一点上还没有被初始化,所以我不太明白你的建议是什么? – user9145300

回答

0

您的问题似乎是%%i%i%完全是不同变量。您不能将值分配给%%i - 只有for命令可以。

您似乎试图执行插入排序来构建排序的字符串列表。您的代码结构可能是编辑遗留下来的问题,但在发布后,该例程将通过流程重新输入。此外,由于例程:test被包含在setlocal/endlocal括号中,所以在:test例程之外将不会看到对list的更改。并且连续有两个setlocal命令创建两个嵌套的本地环境。 两个的选项可以在一个setlocal声明中同时指定。需要注意的是setlocal是不是交换机 - 它建立了一个本地环境(是的,微软已经要求建立delayed expansion等作为像echo on/off独立的马桶盖式操作)

另外请注意,您生成的列表中包含一个前导空格。我注视着下面的替代例程想法:

REM

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都保证在输入中只出现一次。

+0

嗨magoo,谢谢你的线索。它看起来像我没有正确解释我需要什么:原始脚本应该definitly交换列表中的两个给定的元素。我已经想出了如何对列表进行排序(例如使用'sort',或者像使用'lss'或'leq'等示例)。仍然是我的问题是,我无法知道如何在我交换时跳过收集'%% i'和'%% j''',因此'List'中的重复条目。让我们看看如何解决这个问题... – user9145300

+0

也许你应该告诉我们你的期望结果列表应该是什么,给出你的出发名单。 – Magoo

+0

当然,对不起,我应该直接在问题中完成。我试图让列表看起来像这样:'abcd efgh ijkl mnopq qwert rstvw yxcva rtzewrw yxvys'其中'fst'(用于第一个元素)和'scnd'(第二个元素)被交换。就像我刚才提到的原始问题一样,它们已经被交换,但之后它们再次被推入列表中,因此重复输入... – user9145300