中国DOS联盟论坛

中国DOS联盟

-- 联合DOS 推动DOS 发展DOS --

联盟域名:www.cn-dos.net  论坛域名:www.cn-dos.net/forum
DOS,代表着自由开放与发展,我们努力起来,学习FreeDOS和Linux的自由开放与GNU精神,共同创造和发展美好的自由与GNU GPL世界吧!

游客:  注册 | 登录 | 命令行 | 会员 | 搜索 | 上传 | 帮助 »
中国DOS联盟论坛 » DOS批处理 & 脚本技术(批处理室) » [讨论]MSDOS环境下获取并分解系统时钟信息的批处理
作者:
标题: [讨论]MSDOS环境下获取并分解系统时钟信息的批处理 上一主题 | 下一主题
willsort
元老会员

Batchinger


积分 4432
发帖 1512
注册 2002-10-18
状态 离线
『楼 主』:  [讨论]MSDOS环境下获取并分解系统时钟信息的批处理

To All:

      今天,根据网上的一段代码[1]修改出一个可以在MSDOS下获取并分解系统时钟信息(日期、时间)的批处理。在MSDOS6.22/MSDOS7.10下运行通过。显然易见的是,程序的冗余度过高,存在大量的重复代码,所以它需要简化,也必然可以简化。本来是要自己修改的,只是最近还在忙其他的题目,无法分心;同时又感觉论坛讨论纯DOS批处理的主题日趋萎缩,所以将它贴上来,大家讨论一下,看有什么好的简化和改进方案,并对其中涉及到的DOS下的词法分析算法进行讨论和优化。当然,网上的此类代码应该还有许多,大家也可以提供更多的资源链接或者自己的想法。

[1] %time%...DOS vs. Win98
http://groups.google.com/group/alt.msdos.batch/browse_thread/thread/faa7a7961815c004/7c979271a52e36e7
@echo off
if "%1"=="[(" goto parse
echo.|date|find "Current" > _getdate.bat
echo set _dw=%%3> current.bat
echo set _date=%%4>> current.bat
call _getdate.bat

echo.|date|find "Enter" > _getdfmt.bat
echo set _dfmt=%%3> enter.bat
call _getdfmt.bat

echo.|time|find "Current" > _gettime.bat
echo set _time=%%3> current.bat
call _gettime.bat

echo _|choice /c%_dfmt%%_date%_%_time%_ @%0 > _parse.bat
%comspec% /e:2048 /c _parse.bat
goto end

:parse
set _dt1=_%2%3
set _dt2=_%5%6
set _dt3=_%8%9
for %%t in ([,Y,Y,-,M,M,-,D,D,]) do shift

set _vdt=
:loop1
shift
set _tmp=%_vdt%
for %%t in (1,2,3,4,5,6,7,8,9,0) do if "%1"=="%%t" set _vdt=%_vdt%%1
if not "%_vdt%"=="%_tmp%" goto loop1
set %_dt1%=%_vdt%

set _vdt=
:loop2
shift
set _tmp=%_vdt%
for %%t in (1,2,3,4,5,6,7,8,9,0) do if "%1"=="%%t" set _vdt=%_vdt%%1
if not "%_vdt%"=="%_tmp%" goto loop2
set %_dt2%=%_vdt%

set _vdt=
:loop3
shift
set _tmp=%_vdt%
for %%t in (1,2,3,4,5,6,7,8,9,0) do if "%1"=="%%t" set _vdt=%_vdt%%1
if not "%_vdt%"=="%_tmp%" goto loop3
set %_dt3%=%_vdt%

set _vdt=
:loop4
shift
set _tmp=%_vdt%
for %%t in (1,2,3,4,5,6,7,8,9,0) do if "%1"=="%%t" set _vdt=%_vdt%%1
if not "%_vdt%"=="%_tmp%" goto loop4
set _HH=%_vdt%

set _vdt=
:loop5
shift
set _tmp=%_vdt%
for %%t in (1,2,3,4,5,6,7,8,9,0) do if "%1"=="%%t" set _vdt=%_vdt%%1
if not "%_vdt%"=="%_tmp%" goto loop5
set _MN=%_vdt%

set _vdt=
:loop6
shift
set _tmp=%_vdt%
for %%t in (1,2,3,4,5,6,7,8,9,0) do if "%1"=="%%t" set _vdt=%_vdt%%1
if not "%_vdt%"=="%_tmp%" goto loop6
set _SS=%_vdt%

set _vdt=
:loop7
shift
set _tmp=%_vdt%
for %%t in (1,2,3,4,5,6,7,8,9,0) do if "%1"=="%%t" set _vdt=%_vdt%%1
if not "%_vdt%"=="%_tmp%" goto loop7
set _CS=%_vdt%

echo DTN:%_YY% %_MM% %_DD% %_HH% %_MN% %_SS% %_CS%
:end
[ Last edited by willsort on 2006-3-26 at 23:01 ]



※ Batchinger 致 Bat Fans:请访问 [讨论]批处理编程的异类 ,欢迎交流与共享批处理编程心得!
2006-3-26 23:00
查看资料  发送邮件  发短消息 网志   编辑帖子  回复  引用回复
chenall
银牌会员




积分 1276
发帖 469
注册 2002-12-23
来自 福建泉州
状态 离线
『第 2 楼』:  

我来贴一个,效率没有提高.减少了一些代码
@echo off
if "%1"=="[(" goto parse
echo.|date|find "Current" > _getdate.bat
echo set _dw=%%3> current.bat
echo set _date=%%4>> current.bat
call _getdate.bat

echo.|date|find "Enter" > _getdfmt.bat
echo set _dfmt=%%3> enter.bat
call _getdfmt.bat

echo.|time|find "Current" > _gettime.bat
echo set _time=%%3> current.bat
call _gettime.bat

echo _|choice /c%_dfmt%%_date%_%_time%_ @%0 > _parse.bat
%comspec% /e:2048 /c _parse.bat
goto end

:loop
set _vdt=

:loop1
shift
set _tmp=%_vdt%
for %%t in (1,2,3,4,5,6,7,8,9,0) do if "%1"=="%%t" set _vdt=%_vdt%%1
if not "%_vdt%"=="%_tmp%" goto loop1
set %_set%=%_vdt%
goto %next%


:parse
set _dt1=_%2%3
set _dt2=_%5%6
set _dt3=_%8%9
set fgf=%4
for %%t in ([,Y,Y,-,M,M,-,D,D,]) do shift

:dt1
set _set=%_dt1%
set next=dt2
goto loop

:dt2
set _set=%_dt2%
set next=dt3
goto loop

:dt3
set _set=%_dt3%
set next=hh
goto loop

:hh
set _set=_hh
set next=MN
goto loop

:mn
set _set=_mn
set next=ss
goto loop

:ss
set _set=_ss
set next=cs
goto loop

:cs
set _set=_cs
set next=echo1
goto loop

:echo1
echo DTN:%_YY% %_MM% %_DD% %_HH% %_MN% %_SS% %_CS%
:end
[ Last edited by chenall on 2006-3-27 at 13:47 ]



QQ:366840202
http://chenall.net
2006-3-27 13:46
查看资料  发送邮件  访问主页  发短消息 网志  OICQ (366840202)  编辑帖子  回复  引用回复
willsort
元老会员

Batchinger


积分 4432
发帖 1512
注册 2002-10-18
状态 离线
『第 3 楼』:  

Re chenall:

      今天有闲可以回顾修改这个程序了,解决这个代码的冗余性问题,其实最主要的就是如何实现一系列变量连续性的取值和赋值。本来打算使用for对变量进行循环探测,遇到未赋值的变量即跳出赋值,但是此算法实现起来较为复杂,而且对最初变量的重复探测问题也是代码冗余性的一种表现。现在,看到兄的代码,联想起可以使用数据结构中的链表结构,而它正可通过命令行参数来实现,所以写下了这个修改版本。

      这个版本,同时解决了变量没有被“传出”的问题,也增加了退出前清扫现场的语句。但是这个程序还存在许多缺陷,最致命的是,程序中的词法分析核心 choice 无法正确分析以/作为分隔符的字符串,而诸如国家代码为001(United States)的日期信息恰是以/作为分隔符,而代码中的所有语句都是以不依赖于“国家或区域代码”的通用性为设计目标,而这个缺陷完全架空了其他语句所作的努力。

      另外,它还无法处理时间信息中的12小时制时间。
@echo off
if "%1"==":" goto %2
echo.|date|find "Current" > _getdate.bat
echo set _dw=%%3> current.bat
echo set _date=%%4>> current.bat
call _getdate.bat

echo.|date|find "Enter" > _getdfmt.bat
echo set _dfmt=%%3> enter.bat
call _getdfmt.bat

echo.|time|find "Current" > _gettime.bat
echo set _time=%%3> current.bat
call _gettime.bat

echo _|choice /c"%_dfmt%%_date%_%_time%" @%0 : parse > _parse.bat
%comspec% /e:2048 /c _parse.bat
call _setdt.bat
for %%e in (_date _dfmt _time) do set %%e=
for %%f in (_*.bat enter.bat* current.bat*) do del %%f
echo DTN:%_YY%-%_MM%-%_DD% %_HH%:%_MN%:%_SS%.%_CS%
goto end

:parse
set _me=%0
shift
shift
set _tok=%2%3 %5%6 %8%9 HH MN SS CS
for %%t in ([,Y,Y,-,M,M,-,D,D,]) do shift

:NextToken
set _vdt=
:GetToken
shift
set _tmp=%_vdt%
for %%t in (1,2,3,4,5,6,7,8,9,0) do if "%1"=="%%t" set _vdt=%_vdt%%1
if not "%_vdt%"=="%_tmp%" goto GetToken
if "%1"=="" goto end
call %_me% : SetToken %_tok%
goto NextToken

:SetToken
set _tok=%4 %5 %6 %7 %8 %9
echo set _%3=%_vdt%>> _setdt.bat
goto end

:end




※ Batchinger 致 Bat Fans:请访问 [讨论]批处理编程的异类 ,欢迎交流与共享批处理编程心得!
2006-3-29 17:02
查看资料  发送邮件  发短消息 网志   编辑帖子  回复  引用回复
willsort
元老会员

Batchinger


积分 4432
发帖 1512
注册 2002-10-18
状态 离线
『第 4 楼』:  

Re All:

      在[1]找到了解决choice对/的兼容性问题,可以支持001的时钟信息了;而prompt的选择不仅简化了代码,同时还使时间保持为24小时制。对帖中代码进行了简单的修改得到以下代码,未进行日期变量名的匹配。

[1] alt.msdos.batch > Documentation of CHOICE streaming parser
http://groups.google.com/group/a ... sg/5e1d0f360f172118
@echo off
if "%1"==":" goto %2 (subroutine handler at %2)

echo.exit|%comspec%/e:4096/k prompt set v=$d $t$_:>_tm.bat
call _tm.bat
echo.%v%&|%comspec%/e:4096/c %0 : Parse>_tm.bat
for %%p in (_tm.bat* _tmset.bat*) do call %%p

echo.Note that d1 d2 and d3 are in your system date order
echo.DTN:d1=%d1% d2=%d2% d3=%d3% hh=%hh% mm=%mm% ss=%ss% cs=%cs%.

for %%e in (v d1 d2 d3 hh mm ss cs) do set %%e=
for %%f in (_tm.bat* _tm.tmp* _tmset.bat*) do del %%f
goto end

:Parse (usage: call %0 : Parse +input redirect date/time)
set me=%0
set tok=d1 d2 d3 hh mm ss cs
set d1=
:NextToken
for %%v in (v1 v) do set %%v=
choice /c&0123456789 /n>_tm.tmp
for %%n in (0 1 2 3 4 5 6 7 8 9) do if errorlevel 77%%n set v=%%n
if not errorlevel 2 %me% : SetToken %tok%
find ""<_tm.tmp>nul
if not errorlevel 1 if not "%d1%"=="" call %me% : SetToken %tok%
set d1=%d1%%v%
goto NextToken

:SetToken
set tok=%4 %5 %6 %7 %8 %9
echo set %3=%d1%>> _tmset.bat
set d1=
goto end

:end (end-of-file)




※ Batchinger 致 Bat Fans:请访问 [讨论]批处理编程的异类 ,欢迎交流与共享批处理编程心得!
2006-3-30 23:14
查看资料  发送邮件  发短消息 网志   编辑帖子  回复  引用回复
HUNRYBECKY
银牌会员





积分 1179
发帖 442
注册 2006-9-9
状态 离线
『第 5 楼』:  

厉害,看了下英文,看不懂。

2006-12-14 02:26
查看资料  发送邮件  发短消息 网志   编辑帖子  回复  引用回复
tyh
初级用户





积分 80
发帖 43
注册 2007-4-21
状态 离线
『第 6 楼』:  

我来积分。

2007-5-25 10:57
查看资料  发送邮件  发短消息 网志   编辑帖子  回复  引用回复
javenhmh
新手上路





积分 4
发帖 2
注册 2007-3-21
状态 离线
『第 7 楼』:  

厉害,顶顶顶啊~~````

2007-7-1 17:56
查看资料  发送邮件  发短消息 网志   编辑帖子  回复  引用回复
BWSkyer
中级用户

我是DOS学者


积分 367
发帖 180
注册 2006-5-14
来自 重庆
状态 离线
『第 8 楼』:  

提示 bad command or file name..

貌似
echo.exit|%comspec%/e:4096/k prompt set v=$d $t$_:>_tm.bat
call _tm.bat
echo.%v%&|%comspec%/e:4096/c %0 : Parse>_tm.bat
for %%p in (_tm.bat* _tmset.bat*) do call %%p

这里出了问题... 我是DOS6.22, 应该不会啊...



My blog:左铅右椠 上善若水
My team: 519创意团队
2008-10-27 15:33
查看资料  发送邮件  访问主页  发短消息 网志  OICQ (309843581)  编辑帖子  回复  引用回复

请注意:您目前尚未注册或登录,请您注册登录以使用论坛的各项功能,例如发表和回复帖子等。


可打印版本 | 推荐给朋友 | 订阅主题 | 收藏主题



论坛跳转: