微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

批处理文件:使用比较变量的结果?

如何解决批处理文件:使用比较变量的结果?

这里是示例:

set /a "number1=1"
set /a "number2=10"
if %number1% LSS %number2% (set /a "number1=%number1%+1")
echo result=%number1%

代码显示

result=2

是否可以在批处理文件中将if语句更改为以下内容

set /a "number1=%number1%+(%number1% LSS %number2%)"

此时更改的代码显示

Unbalanced parenthesis.
result=1

解决方法

set /A command没有比较运算符。

但是,如果第一个数字小于第二个数字,则有一种方法可以比较两个数字并获得-1的值。为此,我们需要知道逻辑右移运算符>>实际上执行算术移位,这意味着代表符号的最高有效位的值向左移,因此当前保持数字的符号。

例如:

  • 向右移动一位的数字+10(二进制表示00000000 00000000 00000000 00001010)变为+5(二进制表示00000000 00000000 00000000 00000101);
  • 向右移动一位的数字-10(二进制表示11111111 11111111 11111111 11110110)变为-5(二进制表示11111111 11111111 11111111 11111011);

当我们向右移动31个(或更多)位位置时,结果是符号位的32倍(因为我们有32位带符号的整数),结果是-1的值为负输入值,0输入其他值。

当我们现在应用此技术时,它将导致我们找到以下代码:

set /A "number1=%number1%-((%number1%-%number2%)>>31)"

由于%会将任何不代表数字或运算符的字符串解释为变量名,因此您可以省略周围的set /A符号:

set /A "number1=number1-((number1-number2)>>31)"

这可以使用适当的赋值运算符进一步简化:

set /A "number1-=(number1-number2)>>31"
,

因此,您在寻找函数或宏之类的东西时可以将值传递给评估吗?

下面是一个宏,演示了该概念。这不是一个完整的解决方案,因为应该对字符串进行填充,使它们在评估之前具有相等的长度

@Echo Off
 Set "Compare=Set "$RV="&For %%n in (1 2)Do if %%n==2 (For /F "Tokens=1,2 Delims={}" %%G in ("!Strings!")Do ((If "%%~G" LSS "%%~H" (Set "$RV=LSS") Else If "%%~G" EQU "%%~H" (Set "$RV=EQU") Else If "%%~G" GTR "%%~H" (Set "$RV=GTR"))&Echo/%%~G !$RV! %%~H))Else Set Strings="
 Setlocal EnableDelayedExpansion
rem // example usage
 %Compare:$RV=Ex[1]%{one}{oneb}
 %Compare:$RV=Ex[2]%{one}{one}
 %Compare:$RV=Ex[3]%{oneb}{one}
 %Compare:$RV=Ex[4]%{13}{02}
 %Compare:$RV=Ex[5]%{02}{13}
Echo/rem // Integers need to be 0 prefixed and strings should be padded to equal length or will return false:
 %Compare:$RV=Ex[6]%{2}{13}
 %Compare:$RV=Ex[7]%{two}{oneplus}
 Set Ex[

下面是完全实现的比较宏,可填充字符串以防止在字符串长度不同时产生错误的结果。为了便于阅读,使用\n换行语法定义了该宏,但是还包括了复合版本。

@Echo Off & Setlocal DISABLEdelayedexpansion
rem // Pads string with 125 characters to prevent false results when string lengths differ. If comparing strings exceeding 125 characters in length,rem // increase length of the padding and adjust s1 and s2 Substring modification length to match the number of padding characters.
 Set "PAD=00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"
(Set \n=^^^
%= Newline Variable. Do not Modify. =%
)
 Set Compare=Set "$RV=" ^& For %%n in (1 2)Do if %%n==2 (%\n%
  For /F "Tokens=1,2 Delims={}" %%G in ("!Strings!")Do (%\n%
   Set "s1=!PAD!%%~G" ^& Set "s1=!s1:~-125!" ^& Set "s2=!PAD!%%~H" ^& Set "s2=!s2:~-125!"%\n%
   If "!s1!" LSS "!s2!" (Set "$RV=LSS")%\n%
   If "!s1!" EQU "!s2!" (Set "$RV=EQU")%\n%
   If "!s1!" GTR "!s2!" (Set "$RV=GTR")%\n%
   Echo/%%~G !$RV! %%~H%\n%
  )%\n%
 )Else Set Strings=
 Setlocal ENABLEdelayedexpansion
rem // example usages
For %%A in (one two three)Do for %%B in (three two one)Do  %Compare:$RV=Ex[0]%{%%A}{%%B}
 %Compare:$RV=Ex[1]%{one}{oneb}
 %Compare:$RV=Ex[2]%{one}{one}
 %Compare:$RV=Ex[3]%{oneb}{one}
 %Compare:$RV=Ex[4]%{13}{2}
 %Compare:$RV=Ex[5]%{2}{13}
 Set Ex[
Endlocal & Endlocal & Goto :Eof
rem // compound version of Compare Macro:
 Set "Compare=Set "$RV="&For %%n in (1 2)Do if %%n==2 (For /F "Tokens=1,2 Delims={}" %%G in ("!Strings!")Do (Set "s1=!PAD!%%~G"&Set "s2=!PAD!%%~H"&Set "s1=!s1:~-125!"&Set "s2=!s2:~-125!"&(If "!s1!" LSS "!s2!" (Set "$RV=LSS") Else If "!s1!" EQU "!s2!" (Set "$RV=EQU") Else If "!s1!" GTR "!s2!" (Set "$RV=GTR"))&Echo/%%~G !$RV! %%~H&Set "s1="&Set "s2=")) Else Set Strings="
  • 比较宏区分大小写。如果您需要忽略大小写,请更改宏中的If条件以包括/I开关

要在所需上下文中使用宏,请执行以下操作:

 (%compare%{String 1}{String 2}) > Nul & If "!$RV!"=="LSS" (Echo/true)& Rem // replace Echo command within Parantheses with desired command
  • 字符串1和2代表您要比较的任何变量或For循环令牌。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。