China DOS Union

-- Unite DOS · Advance DOS · Grow DOS --

Union site: www.cn-dos.net Forum site: www.cn-dos.net/forum
DOS stands for freedom, openness and progress. Let us work hard, learn from the openness and GNU spirit of FreeDOS and Linux, and together build and grow a free GNU GPL world!

中国DOS联盟论坛
The time now is 2026-07-15 00:34
中国DOS联盟论坛 » DOS批处理 & 脚本技术(批处理室) » SOS!!!!!!Ask about variable delay! View 1,567 Replies 8
Original Poster Posted 2006-11-04 14:30 ·  中国 江西 南昌 电信
初级用户
Credits 78
Posts 30
Joined 2006-06-17 18:01
20-year member
UID 57168
Gender Female
From 湖南湘潭
Status Offline
setlocal EnableDelayedExpansion
set m=0
for /f "tokens=*" %%m in ('findstr /v /C:"730 730" cover.ps') do (

if !m! == 686 (pause) else (echo %%m >>cover3.txt)
set /a m=!m! + 1

)

paus
exit

This is a batch script written by brother kcdsw. He himself said there are the following problems:

If you use set and then echo, then the % in the text will be replaced.
If you use call without enabling variable delay, when passing %%m from for to call, things will also be lost.
So I still enabled variable delay, and the result is that the! are all gone. I hope experts can give advice.

I want to put aside these problems for now.
I want to ask experts to explain according to this example how variable delay works and why it is delayed.
From the sentence above "If you use call without enabling variable delay, when passing %%m from for to call, things will also be lost", I guess it is because parameters cannot be passed between the two segments, and variable delay is used. I have checked a lot on the Internet and still don't fully understand variable delay, so I hope experts will focus on explaining.

[ Last edited by yuanzijia08 on 2006-11-4 at 02:31 PM ]
Floor 2 Posted 2006-11-04 14:35 ·  中国 江西 南昌 电信
初级用户
Credits 78
Posts 30
Joined 2006-06-17 18:01
20-year member
UID 57168
Gender Female
From 湖南湘潭
Status Offline
```batch
@echo off
set m=0
for /f "tokens=*" %%m in ('findstr /v /C:"730 730" cover.ps') do (
set line=%%m
call :Output
set /a m+=1
)
pause
exit

:Output
if "%m%" == "686" (pause) else (echo %line% >>cover3.txt)
goto :eof
```

This is a version rewritten by an elder to help kcdsw solve the problem. It turns off variable delay and uses call. I want to ask experts to talk about the differences between enabling variable delay and turning off variable delay based on these two examples.

Thanks a lot!!!!!
Floor 3 Posted 2006-11-04 16:16 ·  中国 广东 佛山 广东睿江科技有限公司
荣誉版主
★★★★
batch fan
Credits 5,226
Posts 1,737
Joined 2006-03-10 00:38
20-year member
UID 51697
From 成都
Status Offline
The essence of this version has the answer to this question, why go outside to look for it? Please see: When should variable delay be used?
尺有所短,寸有所长,学好CMD没商量。
考虑问题复杂化,解决问题简洁化。
Floor 4 Posted 2006-11-04 22:47 ·  中国 江西 南昌 电信
初级用户
Credits 78
Posts 30
Joined 2006-06-17 18:01
20-year member
UID 57168
Gender Female
From 湖南湘潭
Status Offline
The essence version of the tutorial is definitely not suitable for beginners. I asked after reading it many times. Personally, I think it's better to analyze it with an example.

I first assume the program is like this: (missing a setlocal EnableDelayedExpansion, that is, not enabling variable delay)
set m=0
for /f "tokens=*" %%m in ('findstr /v /C:"730 730" cover.ps') do (

if !m! == 686 (pause) else (echo %%m >>cover3.txt)
set /a m=!m! + 1

)

paus
exit

There are these sentences in the essence version:
The behavior of the command interpreter expanding environment variables is roughly as follows: First, read a complete statement of the command line. After some preliminary preprocessing, before the command is interpreted and executed, it will match the strings closed by percent signs in it. If a matching environment variable is found in the environment space, its value will replace the original string and the percent sign itself. If no match is obtained, an empty string will replace it. This process is the "expansion" of the environment variable, which still belongs to the preliminary preprocessing category of the command line.

After some preliminary preprocessing, before the command is interpreted and executed, it will match the strings closed by percent signs in it

Doesn't this mean that before the execution of the statement for /f "tokens=*" %%m in ('findstr /v /C:"730 730" cover.ps') do (

if !m! == 686 (pause) else (echo %%m >>cover3.txt)
set /a m=!m! + 1
)
it will match the strings closed by percent signs? Then it's okay! When the for statement reads the first line of ('findstr /v /C:"730 730" cover.ps') this data, m=0, then m=1, 2, 3....... As long as before the execution of if !m! == 686 (pause) else (echo %%m >>cover3.txt), replace!m! with its value. What's wrong with this? Why do we still need to enable variable delay?
How does this program execute step by step after enabling variable delay?
Floor 5 Posted 2006-11-04 23:07 ·  中国 广东 佛山 广东睿江科技有限公司
荣誉版主
★★★★
batch fan
Credits 5,226
Posts 1,737
Joined 2006-03-10 00:38
20-year member
UID 51697
From 成都
Status Offline
Since the !m! format is used, it means that the delayed expansion function of variables is enabled. Therefore, the setlocal EnableDelayedExpansion statement must not be missing; otherwise, CMD cannot parse !m!.
尺有所短,寸有所长,学好CMD没商量。
考虑问题复杂化,解决问题简洁化。
Floor 6 Posted 2007-01-20 08:32 ·  中国 山西 运城 联通
元老会员
★★★★
Batchinger
Credits 4,432
Posts 1,512
Joined 2002-10-18 00:00
23-year member
UID 19
Gender Male
Status Offline
Re: yuanzijia08:

From the above discussion, brother indeed has carried out a more in-depth thinking on "variable delayed expansion".

The misunderstanding of brother is that he has not thoroughly understood the concept of "complete statement" mentioned in my original document.

That is to say, for cmd that interprets and executes batch processing, the following code is just "one" statement, which we can call a "compound statement". Of course, Microsoft official does not call it like this.

for /f "tokens=*" %%m in ('findstr /v /C:"730 730" cover.ps') do (
if !m! == 686 (pause) else (echo %%m >>cover3.txt)
set /a m=!m! + 1
)

And before this statement is interpreted and executed, all % are escaped and replaced, including %%m which is also replaced into %m. And if there is %m% in it, it will directly replace into a relatively fixed "constant", and it will no longer be a variable; that is to say, no matter what changes are made to variable m inside for, it can only be perceived after the for statement is executed. Inside for, %m% has no longer changed.

But the actual situation is that we often need to perceive a variable dynamically changing in for statement, because we need to use these changes to complete some application implementations. So, cmd introduced the mechanism of delayed expansion and special escape symbol !.

At this time, cmd still follows the above-mentioned mechanism for the processing of %, but it performs another way of parsing the variables enclosed by !! which were not processed originally. When cmd analyzes the for statement, it still reads in the "whole sentence", preprocesses, expands variables, etc., and then starts the processing flow inside the for statement, which is equivalent to using a streamlined cmd loop to execute another batch processing. In this process, the !! string that is not processed outside for will be expanded in a similar way to %% variables, and this expansion process is similar to interpreting an ordinary batch processing file.

In short, before enabling delay, all variables in the code are already replaced before the code in () is executed; and after enabling delay, the replacement work is delayed until before each statement in () is executed.

The same working mechanism exists in if/else compound statements, any compound statements enclosed by () and compound statements connected by |, &, &&, ||.

In addition, it needs to be explained that variables in cmd also have the distinction between global and local, but this distinction is not divided by () which is similar to the statement block in C language. For example, if we define a variable in the for statement, then after the for is executed, this variable still exists. This has no substantial connection with the variable delayed expansion we are discussing.

[ Last edited by willsort on 2007-1-20 at 09:23 AM ]
※ Batchinger 致 Bat Fans:请访问 批处理编程的异类 ,欢迎交流与共享批处理编程心得!
Floor 7 Posted 2007-01-20 08:34 ·  中国 四川 成都 教育网
铂金会员
★★★★
Credits 7,493
Posts 2,672
Joined 2005-09-02 00:00
20-year member
UID 42173
Gender Male
Status Offline
Sofa, occupy a position to worship the post of willsort

[ Last edited by electronixtar on 2007-1-20 at 08:41 AM ]

C:\>BLOG http://initiative.yo2.cn/
C:\>hh.exe ntcmds.chm::/ntcmds.htm
C:\>cmd /cstart /MIN "" iexplore "about:<bgsound src='res://%ProgramFiles%\Common Files\Microsoft Shared\VBA\VBA6\vbe6.dll/10/5432'>"
Floor 8 Posted 2007-01-20 08:44 ·  中国 甘肃 平凉 电信
金牌会员
★★★★
Credits 4,103
Posts 1,744
Joined 2006-01-20 13:00
20-year member
UID 49241
Gender Male
From 甘肃.临泽
Status Offline
I've benefited a lot from willsort's post
Floor 9 Posted 2007-01-20 09:03 ·  中国 广东 广州 天河区 电信
金牌会员
★★★★
一叶枝头,万树皆春
Credits 2,564
Posts 1,127
Joined 2006-12-25 22:57
19-year member
UID 74552
Gender Male
Status Offline
There are many things that you understand but just can't put into words. This is the difference between a craftsman and a master.
-------Little Bricklayer everest79
Forum Jump: