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-08-02 02:27
中国DOS联盟论坛 » DOS批处理 & 脚本技术(批处理室) » [Recommended][Discussion] K&H home - NT/Win2k scripting View 1,194 Replies 7
Original Poster Posted 2006-08-19 14:12 ·  中国 北京 联通
银牌会员
★★★
DOS联盟捡破烂的
Credits 1,144
Posts 425
Joined 2005-10-20 00:00
20-year member
UID 43784
From 北京
Status Offline
Floor 2 Posted 2006-08-19 14:32 ·  中国 四川 成都 教育网
铂金会员
★★★★
Credits 7,493
Posts 2,672
Joined 2005-09-02 00:00
20-year member
UID 42173
Gender Male
Status Offline
A post that's 34 screens long~~ sigh~~

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 3 Posted 2006-08-20 17:59 ·  中国 广东 云浮 电信
荣誉版主
★★★
Credits 718
Posts 313
Joined 2005-09-26 00:00
20-year member
UID 42844
Gender Male
Status Offline
bagpipe, I don't know whether you noticed it, but I found there's a trick in this:



:exec
%*
goto :eof




But I still can't quite make sense of it for now. Heh. We'll have to ask willsort and the other three moderators for a deeper explanation.


Also, to willsort:
I think the following code isn't much less efficient than what we discussed before here:a question about randomly getting file names


@echo off
setlocal
set _i=0
for %%a in (*) do (
call :exec set /a _i+=1
call :exec echo %%_i%%: %%a
)
endlocal
goto :eof

:exec
%*
goto :eof

goto :eof




[ Last edited by 220110 on 2006-8-20 at 21:36 ]
Floor 4 Posted 2006-08-21 02:33 ·  中国 北京 海淀区 IDC机房
中级用户
★★
Credits 256
Posts 93
Joined 2006-03-26 22:12
20-year member
UID 52853
Gender Male
From 广东
Status Offline
Re: brother bagpipe
A lot of very good batch files! Your post is really nice!

Re: brother 220110

The function of this batch file is to number all the files in the current directory in order!
@echo off
setlocal
set _i=0
for %%a in (*) do (
call :exec set /a _i+=1
call :exec echo %%_i%%: %%a
)
endlocal
goto :eof

:exec
%*
goto :eof

goto :eof



After removing part of the code, the execution result is the same; so the :exec label in the batch file above should be redundant! When calling the :exec label, no parameters are being passed

%* is %1 %2 %3 ...

@echo off
setlocal
set _i=0
for %%a in (*) do (
call set /a _i+=1
call echo %%_i%%: %%a
)
endlocal
Floor 5 Posted 2006-08-21 08:59 ·  中国 北京 联通
银牌会员
★★★
DOS联盟捡破烂的
Credits 1,144
Posts 425
Joined 2005-10-20 00:00
20-year member
UID 43784
From 北京
Status Offline
As long as someone reads it, I'm fully satisfied........... after all, it's a post in English, so not many people care about it
Floor 6 Posted 2006-08-22 02:09 ·  中国 山西 运城 联通
元老会员
★★★★
Batchinger
Credits 4,432
Posts 1,512
Joined 2002-10-18 00:00
23-year member
UID 19
Gender Male
Status Offline

───────────────── Moderator Record ─────────────────
Executed by: Will Sort
Action: modified title - 22699 - Let's discuss and study this batch file together
Penalty: deducted the 6 credits awarded for posting this topic, and deducted an additional 2 credits as a penalty for a title rule violation
───────────────── Moderator Record ─────────────────

Re bagpipe:

It's necessary to remind you that the titles of several of your topics have been rather vague. In the past, no action was taken in view of the relatively high quality of the content, and I hope similar problems will not appear again.

Also, please note that for reposted articles you must indicate the original link so readers can check it. Generally there is no need to combine and repost two articles together; if there really is such a need, please add the necessary markers where the texts join.

[ Last edited by willsort on 2006-8-22 at 02:14 ]
※ Batchinger 致 Bat Fans:请访问 批处理编程的异类 ,欢迎交流与共享批处理编程心得!
Floor 7 Posted 2006-08-22 02:47 ·  中国 山西 运城 联通
元老会员
★★★★
Batchinger
Credits 4,432
Posts 1,512
Joined 2002-10-18 00:00
23-year member
UID 19
Gender Male
Status Offline
Re 220110:

As brother doscc said, %* represents the entire command-line argument list starting from %1.

The function of the :exec section should be to execute the passed-in command-line argument list once again as a new independent command line.

The difference between call :exec commands ... and call commands is that the former calls a label section inside the batch file itself, while the latter directly calls internal or external commands.

As for that piece of code, since the functions it implements are not the same, their efficiency is not really comparable.

Re doscc:

>When calling the :exec label, no parameters are being passed

In fact, parameters are being passed, otherwise %* would do nothing at all.

The reason it still works without calling :exec is that call has the characteristic of reconstructing the command-line environment (including the variable environment). Although under xp's cmd, :exec really does seem superfluous, the author's writing environment was NT/2K, which may not have had some of xpcmd's features (for example, delayed variable expansion was not supported before NT4.0(2000)), so a double-call or call :exec calling structure was used.

Also, I added simple comments to the final code in the article command line parameter parsing, as follows:


::@echo off
:: Separate the first argument in the command-line arguments from the remaining arguments
:: file: detach.cmd
:: Example: detach "123 456" abc xyz
::
:: Example: detach 123 " 456 abc" xyz
::

setlocal
set argList=%*
call :detachArg1 argList
echo
goto done

:: if no quotes, this is much simpler:
:: Because FOR/F's lexical analysis does not escape quotation marks, spaces inside quotes cannot be hidden
:: FOR /f "tokens=1*" %%a IN ("%*") DO echo
:: detachArg1 arglistName
:: (split first arg from given argList)
:: detachArg1 = firstArg(*arglistName)
:: *arglistName = argTail(*arglistName)

:detachArg1
set _detachArg1=
if %1.==. goto :eof
call call :firstArg %%%1%%
call set %%^^%0%%=%firstArg%
:: Store the value of firstArg in an environment variable named after the current subroutine label, detachArg
:: The environment variable name does not contain the colon in the label (after the colon is modified by %^ it is escaped to empty), and variables with colons in their names are hard to reference
:: As the author said, the above two lines and the :firstArg section can be simplified to a single line: set detachArg1=%1
call call :argTail %%%1%%
set %1=%argTail%
:: Store the remaining return value of the subroutine, %argTail%, in the environment variable argList having the same name as the subroutine command-line parameter
goto :eof

:: Store the first passed-in argument in the environment variable firstArg, named after the current subroutine label
:firstArg
call set %%^^%0%%=%1
goto :eof

:: Return the command-line argument list without the first argument — the tail of the command line
:: return argument list, without first.
:argTail
set argList=%*
set arg1=%1
if not defined arg1 goto :eof
call :varlength arg1
:: Get the string length of the first argument
call call :trimlist %%argList:~%varlength%%%
:: Cut out the following part of the whole command line according to the length, and save it into trimlist
call set %%^^%0%%=%trimlist%
:: Save the value of %trimlist% into argTail
:: The above two lines and the :trimlist section can be simplified to a single line: call set argTail=%%argList:~%varlength%%%
goto :eof

:: String slicing
:trimlist
call set %%^^%0%%=%*
goto :eof

:: Use brute force to get the string length of environment variable arg1 (the first argument)
:: get length of environment variable (via brute force)
:: %1 name of var to check
:varlength
for /f "tokens=1* delims==" %%y in ('set %1^|findstr /b /i "%1=" ') do (
set vl_val=%%z)
set vl_vlen=0
if not defined vl_val goto lenrpdone
:: trap quoted string
:: Environment variables whose string value contains quotation marks can no longer be enclosed in one pair of quotation marks, so they must be handled differently
if "".==%vl_val:~0,1%%vl_val:~-1%. (
set vl_vlen=2
set vl_val=%vl_val:~1,-1%
) else (
set vl_vlen=0
)
:chklenrpdone
if "%vl_val%"=="" goto lenrpdone
set vl_val=%vl_val:~1%
set /a vl_vlen+=1
goto chklenrpdone
:lenrpdone
call set %%^^%0%%=%vl_vlen%
set vl_vlen=
set vl_val=
goto :EOF

:done
endlocal


[ Last edited by willsort on 2006-8-22 at 02:49 ]
※ Batchinger 致 Bat Fans:请访问 批处理编程的异类 ,欢迎交流与共享批处理编程心得!
Floor 8 Posted 2006-08-22 08:57 ·  中国 北京 联通
银牌会员
★★★
DOS联盟捡破烂的
Credits 1,144
Posts 425
Joined 2005-10-20 00:00
20-year member
UID 43784
From 北京
Status Offline
I really have nothing to say now. I was just about to reach Silver Member, and now this again — have to wait a few more days, sigh
Forum Jump: