【问题标题】:SET Command equivalent in DOS 7DOS 7 中等效的 SET 命令
【发布时间】:2018-09-05 22:15:36
【问题描述】:

我有一台运行 DOS 7.10 的旧 MS DOS 计算机(ver 命令给出:windows 98 ver 4.10.2222)。我必须制作一个基本上运行命令 10 或任何时间的批处理脚本。我尝试使用 for 命令,但它给了我 ILLEGAL Command For 所以现在我有:

@ECHO off
SET COUNT=0

:MyLoop
IF "%COUNT%" == "10" GOTO EndLoop
ECHO %COUNT%
SET /a COUNT+=1
:EndLoop 
ECHO done

但是,这给了我一个 0 的无限循环,好像 set 命令不起作用。不过,该命令在 Windows 10 中的 CMD 中有效。谁能建议我做错了什么?或者一种在 DOS 7 批处理文件中实现 for 循环的方法。

【问题讨论】:

  • @JeffZeitlin - DOS 没有延迟扩展。
  • 我没有要测试的 Windows 98 机器,但我相当肯定这行 set /a count+=1 是问题所在。尝试将其扩展为 set /a count=%count%+1
  • 重读问题,我什至不确定Win98命令行是否支持SET /A; Windows XP 之前的变量——甚至可能是 in XP——总是字符串,而不是数字。我回想起那些日子,为了循环五次,我最终不得不做FOR %I IN (1 2 3 4 5) ...
  • 是的,@JeffZeitlin,在 DOS 中,没有 set /Afor /L 也不是。所以你必须使用for %%I in (1 2 3 ...) do,或者,如果你想使用goto循环,set "COUNT=%COUNT%_"if "%COUNT%"=="___..."
  • 在较新的 Windows 上使用cmd.exe 作为与command.com 兼容的命令解释器很容易测试批处理文件。在较新的 Windows 上使用 setlocal DisableExtensions 启动批处理文件,cmd.exe 解释批处理文件,如 command.comcmd /? 输出(大多数)受启用/禁用命令扩展影响的命令。每个受影响命令的单独帮助解释了哪些功能/选项需要启用的命令扩展。一旦批处理文件在禁用命令扩展的较新 Windows 上运行,就该在 MS-DOS 或 Windows 95/98 上对其进行测试了。

标签: batch-file dos windows-98


【解决方案1】:

此批处理文件执行您的请求。照原样,此示例最多计数 123,但它最多可以计数 999(1000 次,根据您的要求)。如果您需要更多数字,只需添加相应的部分...

EDIT 03/27/2018按照评论中的建议修改了代码

EDIT 03/29/2018第二次尝试

@echo off
if not "%1" == "" goto %1

set myself=%0

set count1=0

:MyLoop
   if "%count3%%count2%%count1%" == "123" goto EndLoop
   echo %count3%%count2%%count1%
   call %myself% :incCount
goto MyLoop
:endLoop
echo Done
goto :EOF


:incCount
call %myself% :incDigit %count1%
set count1=%digit%
if %carry% == 0 goto endIncCount
call %myself% :incDigit %count2%
set count2=%digit%
if %carry% == 0 goto endIncCount
call %myself% :incDigit %count3%
set count3=%digit%
:endIncCount
goto :EOF

:incDigit digit
set carry=0
if not "%2" == "" goto next1
   set digit=1
   goto endIncDigit
:next1
if not %2 == 9 goto next2
   set digit=0
   set carry=1
   goto endIncDigit
:next2
if %2 == 8 set digit=9
if %2 == 7 set digit=8
if %2 == 6 set digit=7
if %2 == 5 set digit=6
if %2 == 4 set digit=5
if %2 == 3 set digit=4
if %2 == 2 set digit=3
if %2 == 1 set digit=2
if %2 == 0 set digit=1
:endIncDigit

:EOF

编辑添加了新方法

这种更简单的方法无需修改即可管理计数器中的任意位数:

@echo off
if not "%1" == "" goto %1

set myself=%0

set count=0

:MyLoop
   call %myself% :incCount 
   echo %printCnt%
if not "%printCnt%" == "123" goto MyLoop
echo Done
goto :EOF


:incCount
set newCnt=
set printCnt=
set carry=1
for %%a in (%count%) do call %myself% :incDigit %%a
set count=%newCnt%
if %carry% == 0 goto :EOF
set count=%count%,1
set printCnt=1%printCnt%
goto :EOF

:incDigit digit
set digit=%2
if %carry% == 0 goto endIncDigit
if not %2 == 9 goto next
   set digit=0
   goto endIncDigit
:next
if %2 == 8 set digit=9
if %2 == 7 set digit=8
if %2 == 6 set digit=7
if %2 == 5 set digit=6
if %2 == 4 set digit=5
if %2 == 3 set digit=4
if %2 == 2 set digit=3
if %2 == 1 set digit=2
if %2 == 0 set digit=1
set carry=0
:endIncDigit
set newCnt=%newCnt%,%digit%
set printCnt=%digit%%printCnt%

:EOF

【讨论】:

  • 不错的尝试,但 command.com 无法调用标签。扩展集语法也是未知的。尽管如此,你的想法的基本原理应该可以工作
  • 如果您不介意,请提供一点帮助,对不起,我有点不确定...如果我尝试按原样实现您的脚本,它会给我语法错误和一个无限循环,输出如下: 0 语法错误
  • 操作!我的错... :(if "%1" neq "" goto %1 更改为if not "%1" == "" goto %1(我已经在代码中这样做了)。如果仍然显示错误,请删除@echo off 行,将"123" 更改为"2",再次运行程序并报告发生错误的确切行...
  • 好的是的,这有帮助,现在循环可以上升到 9,之后它开始给出语法错误。
  • 我尝试删除 & 并按顺序将其设为单独的 if 条件,这使得代码从 1 变为 9,但是在几个循环后,pc 用完了变量的内存空间 if有帮助
【解决方案2】:
for %%a in (1 2 3 4 5 6 7 8 9 10) do echo %%a

应该为你数 1 到 10。

除此之外,您还需要更明确地提出您的要求。

【讨论】:

  • 老实说,该死的希望有一个更优雅的解决方案,因为如果我必须迭代 1000 次,我将不得不数到 1000...
  • 可以的。我们需要知道您正在尝试做什么,因此我们不会为您可能正在做的事情提供所有可能的解决方案。
  • 嗯,好的,所以我正在尝试创建一个批处理文件,我将使用它一次调用两个单独的程序。我有这个光谱仪,它的光圈将由一个程序和一个带光源的步进电机控制,所以基本上我想通过程序 1 逐步打开光圈并读取读数,然后电机将通过程序 2 移动到结束循环并冲洗并重复。所以理论上:有一个循环 i = 1 到 1000 或 w.e. (必须在看到几个结果后决定)调用程序 1
【解决方案3】:

在 MS-DOS 中,/A 命令没有算术选项 /Afor 循环也没有 /L 选项。

所以你要么必须这样做:

@echo off
set COUNT=

:LOOP
if "%COUNT%"=="__________" goto QUIT
set COUNT=%COUNT%_
echo %COUNT%
goto LOOP
:QUIT
echo Done

或者像这样:

@echo off
for %%I in (1 2 3 4 5 6 7 8 9 10) do echo %%I
echo Done

如果您想进行多次迭代,您可以像第一种方法一样帮助自己:

@echo off
rem // This performs 1000 iterations:
set COUNT=
set LIMIT=__________
set LIMIT=%LIMIT%%LIMIT%%LIMIT%%LIMIT%%LIMIT%%LIMIT%%LIMIT%%LIMIT%%LIMIT%%LIMIT%
set LIMIT=%LIMIT%%LIMIT%%LIMIT%%LIMIT%%LIMIT%%LIMIT%%LIMIT%%LIMIT%%LIMIT%%LIMIT%

:LOOP
if "%COUNT%"=="%LIMIT%" goto QUIT
set COUNT=%COUNT%_
echo %COUNT%
goto LOOP
:QUIT
echo Done

或者像第二个这样:

@echo off
rem // This performs 1000 iterations:
for %%I in (1 2 3 4 5 6 7 8 9 10) do for %%J in (1 2 3 4 5 6 7 8 9 10) do for %%K in (1 2 3 4 5 6 7 8 9 10) do echo %%I, %%J, %%K
echo Done

【讨论】:

    【解决方案4】:

    这是一个用于 MS-Dos/Win98 的“通用”增量函数。 值的数字必须用逗号分隔。 结果将存储在同一个变量和用于打印的辅助变量中(不带逗号)。
    该解决方案可以扩展到解决任何算术计算。

    @echo off
    if not "%1" == "" goto %1
    
    set counter=0
    
    :loop
    call %0 :inc counter print_cnt
    echo counter=%print_cnt%
    goto :loop
    goto :eof
    
    REM *************************************
    :inc
    set _self=%0
    set _counterVar=%2
    set _counterPrintVar=%3
    set _rev=
    set _result=
    set _printResult=
    set _carry=1
    call %_self% :GetIndirectVar _counter %_counterVar%
    call %_self% :reverse %_counter%
    set %_counterVar%=%_result%
    set %_counterPrintVar%=%_printResult%
    goto :eof
    
    REM *************************************
    :GetIndirectVar
    for %%a in (%3) do echo set %2=%%%%a%% > tmp.bat
    call tmp.bat
    del tmp.bat
    goto :eof
    
    REM *************************************
    :reverse
    if "%2" == "" goto :_add_start
    set _rev=%2,%_rev%
    shift
    goto :reverse
    
    :_add_start
    for %%a in (%_rev%) do call %_self% :add_digit %%a
    if "%_carry%" == "0" goto :eof
    set _digit=1
    goto :_add_digit_end
    
    REM *************************************
    :add_digit
    set _digit=%2
    rem echo d=%2 carry=%_carry%
    if "%_carry%" == "0" goto :_add_digit_end
    set _carry=0
    
    if "%_digit%" == "9" set _carry=1
    if "%_digit%" == "9" set _digit=0
    if "%_carry%" == "1" goto :_add_digit_end
    if "%_digit%" == "8" set _digit=9
    if "%_digit%" == "7" set _digit=8
    if "%_digit%" == "6" set _digit=7
    if "%_digit%" == "5" set _digit=6
    if "%_digit%" == "4" set _digit=5
    if "%_digit%" == "3" set _digit=4
    if "%_digit%" == "2" set _digit=3
    if "%_digit%" == "1" set _digit=2
    if "%_digit%" == "0" set _digit=1
    
    :_add_digit_end
    set _result=%_digit%,%_result%
    set _printResult=%_digit%%_printResult%
    goto :eof
    
    :eof
    

    您也可以将其用作“外部”增量函数,只需将其命名为“increm.bat”

    @echo off
    set myCounterA=9,9
    call increm.bat :inc myCounterA output
    echo The new value is %output%
    

    【讨论】:

    • 我尝试了你的方法,但是它就像 counter=1 counter=112 1113 1114 等等,直到它在 10^24 左右用完空间..
    • 我刚刚重新测试它并且它可以工作,但我想你在某个地方有一个尾随空格,如set _carry=0<space>,这会破坏函数
    猜你喜欢
    • 2016-02-03
    • 1970-01-01
    • 1970-01-01
    • 2012-04-28
    • 2022-02-06
    • 2018-11-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多