为什么在IF语句后SET / A没有按预期工作?

时间:2017-12-29 10:14:01

标签: batch-file cmd batch-processing

变量_dd_mm保持当前日期和月份。 3必须添加到当天,如果日期大于27,则必须将1添加到月份(将其更改为提前一个月)。

Set /A _dd=%_dd%+3
REM **Set /A _mm=%_mm%+1**
echo %_dd%
IF %_dd% LSS 10 Set _dd=0%_dd%
IF %_dd% GTR 27 (
 Set _dd=01
 Set /A _mm=%_mm%+1
 Set _mm=0%_mm%
 Echo !_mm%! )

Set /A _mm=%_mm%+1 IF 语句之外运行,但不在 IF 语句的操作中。

IF 语句后,为什么 SET / A 命令行无法正常工作?

3 个答案:

答案 0 :(得分:0)

这里几个问题。您正在尝试使用没有setlocal enableDelayedExpansion子句的延迟扩展。根据给定的测试数据,您永远不会输入最后一个IF。您正在括号块内设置值而没有正确使用delayed variable expansion。拥有setlocal / endlocal块会更好。知道这个:

@echo off
:: to use variable expansion with ! you need delayed expansion
setlocal enableDelayedExpansion
Set /A _dd=%_dd%+3
REM **Set /A _mm=%_mm%+1**
echo %_dd%
IF %_dd% LSS 10 Set _dd=0%_dd%
echo %_dd%


::set another value to _dd to match  the last if condition
set /a _dd=30
::::



IF %_dd% GTR 27 (

 Set _dd=01
 Set /A _mm=_mm+1
 Set _mm=0!_mm!
 Echo !_mm%! 

)
endlocal

答案 1 :(得分:0)

问题,(因为看起来你几乎意识到),变量扩展需要在If块中延迟。

Set /A _dd +=3
:: Set /A _mm +=1
Echo %_dd%
If %_dd% Lss 10 Set "_dd=0%_dd%"
IF %_dd% Gtr 27 (
   Set "_dd=01"
   Set /A _mm +=1
  Set "_mm=0!_mm!"
  Echo !_mm! )

在使用延迟扩展之前,您需要确保已使用以下命令启用它:

SetLocal EnableDelayedExpansion

答案 2 :(得分:0)

所有出现的%_mm%在预处理整个命令块期间被替换,从(开始到匹配),然后才执行 IF 条件通过Windows命令解释器。通过在命令提示符窗口中运行批处理文件而不在顶部@echo off可以看到此行为,以便在执行前预处理后输出命令行和整个命令块。

看起来在访问同一命令块中修改的命令块中的环境变量时所需的延迟环境变量扩展并不完全未知,因为行Echo !_mm%!表示虽然语法错误。打开命令提示符窗口,运行set /?并仔细完整地将帮助输出读入窗口。延迟环境变量扩展可以通过 IF 上的命令 SET 和最常使用命令块的 FOR 示例来解释。 SET 的帮助也详细解释了算术表达式。

这是一个解决方案,它不使用延迟环境变量扩展,使用不同的流程,并且处理月值0809也是正确的。有关详细信息,请参见第二个注释块。

rem This integer increment is problematic in case of value is 08 or 09.
rem See the month increment below how to handle such values also correct.
set /A _dd+=3
echo %_dd%

if %_dd% LEQ 27 goto MakeTwoDigitDay
set "_dd=01"

rem 08 and 09 would be interpreted as invalid octal numbers. Therefore do a
rem string concatenation with 1 if the first character is a leading zero for
rem month to change month value from 01-09 to 101-109 to get the month value
rem with a leading 0 interpreted as decimal number and add 1. Otherwise add
rem 101 to months 1-12 with no leading 0. Then assign to month variable
rem just the last two digits of the month value being greater than 100.

if "%_mm:~0,1%" == "0" ( set /A "_mm=1%_mm% + 1" ) else ( set /A "_mm+=101" )
set "_mm=%_mm:~-2%"
echo %_mm%

:MakeTwoDigitDay
if "%_dd:~1%" == "" set "_dd=0%_dd%"

要了解使用的命令及其工作原理,请打开命令提示符窗口,执行以下命令,并完全阅读为每个命令显示的所有帮助页面。

  • echo /?
  • goto /?
  • if /?
  • rem /?
  • set /?