Windows 如何批量反转字符串列表

Windows 如何批量反转字符串列表,windows,batch-file,Windows,Batch File,我在批量脚本中反转字符串列表时遇到问题。假设我有一个列表L=string1,string2,string3,我想得到反向列表L=string3,string2,string1。任何想法???在不知道您的输入是什么样的情况下,这可能是第一次尝试: @ECHO OFF SETLOCAL EnableDelayedExpansion SET var=abc,def,ghi SET rev= :LOOP IF NOT "!var!"=="" ( FOR /F "delims=, tokens=1

我在批量脚本中反转字符串列表时遇到问题。假设我有一个列表L=string1,string2,string3,我想得到反向列表L=string3,string2,string1。任何想法???

在不知道您的输入是什么样的情况下,这可能是第一次尝试:

@ECHO OFF
SETLOCAL EnableDelayedExpansion
SET var=abc,def,ghi
SET rev=
:LOOP
IF NOT "!var!"=="" (
    FOR /F "delims=, tokens=1,*" %%F IN ("!var!") DO (
        SET rev=%%F,!rev!
        SET var=%%G
    )
) ELSE (
    SET rev=!rev:~0,-1!
    GOTO ENDLOOP
)
GOTO LOOP
:ENDLOOP
ECHO reversed list is: !rev!
编辑:根据要求,以下是其工作原理的说明:

var是由逗号分隔的字符串的起始列表。 rev将是反向字符串。开始时,该字符串为空

现在让我们看一下循环:

在每次迭代中,我们将字符串分为两部分:%%F和%%G.%F将是第一个逗号之前的所有内容,%%G将是字符串的其余部分:FOR/F delims=,tokens=1,*%%F In!var!。delims=,表示我们使用逗号作为分隔符。tokens=1,*表示第一个找到的子字符串将存储在%%F中,而其余的子字符串将存储在%%G%%中。F是为第一个令牌定义的,因此Windows命令解释器将在以后将每个令牌放在G、H、I等中-当我们使用*时,所有内容都将放在%%G中。最后,我们获取字符串%%F的第一个令牌并附加,!牧师!去吧。然后,我们将剩余字符串列表设置为第一个逗号%%G后面的所有内容

在第一次迭代中,此循环执行以下伪代码:

var=abc,def,ghi
rev=
split the string into %%F=abc and %%G=def,ghi
set rev to %%F,rev //means abc,
set var to var but without the first token //means def,ghi
在第二次迭代中:

var=def,ghi
rev=abc,
split the string into %%F=def and %%G=ghi
set rev to %%F,rev //means def,abc
set var to var but without the first token //means ghi
var=ghi
rev=def,abc
split the string into %%F=ghi %%G=
set rev to %%F,rev //means ghi,def,abc,
set var to var but without the first token //means empty string
在第三次迭代中:

var=def,ghi
rev=abc,
split the string into %%F=def and %%G=ghi
set rev to %%F,rev //means def,abc
set var to var but without the first token //means ghi
var=ghi
rev=def,abc
split the string into %%F=ghi %%G=
set rev to %%F,rev //means ghi,def,abc,
set var to var but without the first token //means empty string
现在,在跳回:循环之后,if条件不再满足as!瓦尔!已从以前的abc、def、ghi缩减为现在的空字符串。如果不是这样的话!var!==变为false,我们跳到ELSE子句

还有一个问题:当我们通过预先附加原始列表中的第一个标记和一个逗号来构造反向字符串时,我们将在反向字符串列表的末尾使用一个逗号:ghi、def、abc、


设置rev=!牧师:~0,-1!解决了这个问题。它从字符串中提取一个子字符串,从索引0开始,到结尾1结束。所以这一行只是删除了字符串末尾的最后一个。然后我们跳到:ENDLOOP。

在不知道您的输入是什么样子的情况下,这可能是第一次尝试:

@ECHO OFF
SETLOCAL EnableDelayedExpansion
SET var=abc,def,ghi
SET rev=
:LOOP
IF NOT "!var!"=="" (
    FOR /F "delims=, tokens=1,*" %%F IN ("!var!") DO (
        SET rev=%%F,!rev!
        SET var=%%G
    )
) ELSE (
    SET rev=!rev:~0,-1!
    GOTO ENDLOOP
)
GOTO LOOP
:ENDLOOP
ECHO reversed list is: !rev!
编辑:根据要求,以下是其工作原理的说明:

var是由逗号分隔的字符串的起始列表。 rev将是反向字符串。开始时,该字符串为空

现在让我们看一下循环:

在每次迭代中,我们将字符串分为两部分:%%F和%%G.%F将是第一个逗号之前的所有内容,%%G将是字符串的其余部分:FOR/F delims=,tokens=1,*%%F In!var!。delims=,表示我们使用逗号作为分隔符。tokens=1,*表示第一个找到的子字符串将存储在%%F中,而其余的子字符串将存储在%%G%%中。F是为第一个令牌定义的,因此Windows命令解释器将在以后将每个令牌放在G、H、I等中-当我们使用*时,所有内容都将放在%%G中。最后,我们获取字符串%%F的第一个令牌并附加,!牧师!去吧。然后,我们将剩余字符串列表设置为第一个逗号%%G后面的所有内容

在第一次迭代中,此循环执行以下伪代码:

var=abc,def,ghi
rev=
split the string into %%F=abc and %%G=def,ghi
set rev to %%F,rev //means abc,
set var to var but without the first token //means def,ghi
在第二次迭代中:

var=def,ghi
rev=abc,
split the string into %%F=def and %%G=ghi
set rev to %%F,rev //means def,abc
set var to var but without the first token //means ghi
var=ghi
rev=def,abc
split the string into %%F=ghi %%G=
set rev to %%F,rev //means ghi,def,abc,
set var to var but without the first token //means empty string
在第三次迭代中:

var=def,ghi
rev=abc,
split the string into %%F=def and %%G=ghi
set rev to %%F,rev //means def,abc
set var to var but without the first token //means ghi
var=ghi
rev=def,abc
split the string into %%F=ghi %%G=
set rev to %%F,rev //means ghi,def,abc,
set var to var but without the first token //means empty string
现在,在跳回:循环之后,if条件不再满足as!瓦尔!已从以前的abc、def、ghi缩减为现在的空字符串。如果不是这样的话!var!==变为false,我们跳到ELSE子句

还有一个问题:当我们通过预先附加原始列表中的第一个标记和一个逗号来构造反向字符串时,我们将在反向字符串列表的末尾使用一个逗号:ghi、def、abc、


设置rev=!牧师:~0,-1!解决了这个问题。它从字符串中提取一个子字符串,从索引0开始,到结尾1结束。所以这一行只是删除了字符串末尾的最后一个。然后我们跳到:ENDLOOP。

这里是一个批处理文件代码,假设L=string1、string2、string3被分配给一个环境变量:

@echo off
setlocal EnableExtensions DisableDelayedExpansion
set "ListLine=L=string1,string2,string3"
for /F "tokens=1* delims==" %%I in ("%ListLine%") do (
    set "LineBegin=%%I"
    set "ListItems=%%J"
)
set "ReversedItems="
for %%I in (%ListItems%) do call set "ReversedItems=%%I,%%ReversedItems%%"
set "ListLine=%LineBegin%=%ReversedItems:~0,-1%"
echo %ListLine%
endlocal
Windows命令解释器在一个简单的FOR循环中解释字符串列表中的逗号,就像在命令提示符窗口中运行此批处理文件而不使用@echo off时可以看到的空格字符一样。因此,第二个FOR循环首先使用分配给循环变量I的string1运行,第二个使用string2运行,第三个使用string3运行

命令调用用于对命令集进行双重处理,以避免使用延迟环境变量扩展的要求,如运行SET/?时命令集输出的帮助所述?在命令提示窗口中

要了解所使用的命令及其工作方式,请打开命令提示符窗口,在其中执行以下命令,并非常仔细地阅读为每个命令显示的所有帮助页面

呼叫/? 回声/? endlocal/? 对于/? 集/? setlocal/?
以下是一个批处理文件代码,假设L=string1、string2、string3分配给环境变量:

@echo off
setlocal EnableExtensions DisableDelayedExpansion
set "ListLine=L=string1,string2,string3"
for /F "tokens=1* delims==" %%I in ("%ListLine%") do (
    set "LineBegin=%%I"
    set "ListItems=%%J"
)
set "ReversedItems="
for %%I in (%ListItems%) do call set "ReversedItems=%%I,%%ReversedItems%%"
set "ListLine=%LineBegin%=%ReversedItems:~0,-1%"
echo %ListLine%
endlocal
Windows命令解释器解释字符串列表中的逗号 gs在一个简单的FOR循环中类似于空格字符,因为它可以在命令提示符窗口中运行此批处理文件而不使用@echo off。因此,第二个FOR循环首先使用分配给循环变量I的string1运行,第二个使用string2运行,第三个使用string3运行

命令调用用于对命令集进行双重处理,以避免使用延迟环境变量扩展的要求,如运行SET/?时命令集输出的帮助所述?在命令提示窗口中

要了解所使用的命令及其工作方式,请打开命令提示符窗口,在其中执行以下命令,并非常仔细地阅读为每个命令显示的所有帮助页面

呼叫/? 回声/? endlocal/? 对于/? 集/? setlocal/?
您也可以使用这种更短/更简单的方法:

@echo off
setlocal EnableDelayedExpansion

set "L=string1,string2,string3"
echo Input =%L%

set "revL="
set "str=%L:,=" & set "revL=,!str!!revL!" & set "str=%"

set "revL=%str%%revL%"
echo Output=%revL%

此方法使用与其他答案相同的步骤,但行数较少。如果您想知道这里发生了什么,请删除@echo离线并运行它

您也可以使用这种更短/更简单的方法:

@echo off
setlocal EnableDelayedExpansion

set "L=string1,string2,string3"
echo Input =%L%

set "revL="
set "str=%L:,=" & set "revL=,!str!!revL!" & set "str=%"

set "revL=%str%%revL%"
echo Output=%revL%

此方法使用与其他答案相同的步骤,但行数较少。如果您想知道这里发生了什么,请删除@echo离线并运行它

Aacini绝对是所有答案中最快的代码。这是一些使用类似集合技巧的较长代码

@echo off
setlocal EnableDelayedExpansion
set i=1
set "x=abc,def,ghi"
set "x!i!=%x:,=" & set /A i+=1 & set "x!i!=%"
FOR /L %%G IN (%i%,-1,1) DO (
    IF "%i%"=="%%G" (
        set "reverse=!x%%G!"
    ) ELSE (
        set "reverse=!reverse!,!x%%G!"
    )
)
echo %reverse%
pause
只是对所有4个答案进行快速计时测试。第一个在3个逗号分隔的字段中使用原始字符串3个字符。第二个在9个逗号分隔的字段中使用3个字符。每次我都测试了100次,并计算了平均值。差别可以忽略不计

使用3x3平均尝试100次

Aacini    0.39254
Squashman 0.39851
Michael   0.3999
Mofi      0.40434
使用3x9平均尝试100次

Aacini    0.39925
Squashman 0.40278
Michael   0.41457
Mofi      0.43397

Aacini,绝对有所有答案中最快的代码。这是一些使用类似集合技巧的较长代码

@echo off
setlocal EnableDelayedExpansion
set i=1
set "x=abc,def,ghi"
set "x!i!=%x:,=" & set /A i+=1 & set "x!i!=%"
FOR /L %%G IN (%i%,-1,1) DO (
    IF "%i%"=="%%G" (
        set "reverse=!x%%G!"
    ) ELSE (
        set "reverse=!reverse!,!x%%G!"
    )
)
echo %reverse%
pause
只是对所有4个答案进行快速计时测试。第一个在3个逗号分隔的字段中使用原始字符串3个字符。第二个在9个逗号分隔的字段中使用3个字符。每次我都测试了100次,并计算了平均值。差别可以忽略不计

使用3x3平均尝试100次

Aacini    0.39254
Squashman 0.39851
Michael   0.3999
Mofi      0.40434
使用3x9平均尝试100次

Aacini    0.39925
Squashman 0.40278
Michael   0.41457
Mofi      0.43397

谢谢你的解决方案,我想更多地了解你在那里做了什么。你能给我解释一下这个循环是怎么回事吗。我不明白为什么会有!牧师!在这一行的逗号之后,代码集rev=%%F,!牧师!。不知道~0,-1在代码集rev=中做了什么!牧师:~0,-1!再次感谢你,现在我明白了!!!我没有考虑预加,所以我不能理解代码。现在一切都清楚了。谢谢你的解决方案,我想更多地了解你在那里做了些什么。你能给我解释一下这个循环是怎么回事吗。我不明白为什么会有!牧师!在这一行的逗号之后,代码集rev=%%F,!牧师!。不知道~0,-1在代码集rev=中做了什么!牧师:~0,-1!再次感谢你,现在我明白了!!!我没有考虑预加,所以我不能理解代码。现在一切都清楚了。THX与Michael、Aacini和Squashman发布的其他三种解决方案相比,该解决方案有一个优点:它还可以在字符串(如string1!)中使用一个或多个感叹号生成正确的输出!,string2!,string3!。但这对帕兹乔来说可能并不重要。此解决方案在其他3个解决方案工作的字符串中的一个或多个百分号上失败。关于一般数据问题的答案通常不是100%适用于所有可能的用例。这个答案也不例外。与Michael、Aacini和Squashman发布的其他三个解决方案相比,此解决方案有一个优点:它生成正确的输出,并且在字符串中包含一个或多个感叹号,如string1!,string2!,string3!。但这对帕兹乔来说可能并不重要。此解决方案在其他3个解决方案工作的字符串中的一个或多个百分号上失败。关于一般数据问题的答案通常不是100%适用于所有可能的用例。这个答案也不例外。