【技术文章】精彩批处理代码(转)

0 views
Skip to first unread message

zongzi

unread,
Jan 8, 2007, 1:17:46 AM1/8/07
to 中国特色的配置管理
精彩批处理代码


接收键盘输入字符串的程序


:: Get user input - includes error check
@echo off
echo e102'set %%1='> %temp%.\t1.dat
for %%? in (w q) do echo %%?>> %temp%.\t1.dat
:input
echo.
echo Type input:
FC con nul /lb1 /n |FIND "1:" > %temp%.\t2.bat
:: Error checking begins here
FIND "|" %temp%.\t2.bat > nul
if not errorlevel=1 goto error
FIND "=" %temp%.\t2.bat > nul
if not errorlevel=1 goto error
FIND " nul
if not errorlevel=1 goto error
FIND ">" %temp%.\t2.bat > nul
if not errorlevel=1 goto error
:: Error checking end
DEBUG %temp%.\t2.bat nul
call %temp%.\t2.bat 字符串
for %%? in (t1.dat t2.bat) do del %temp%.\%%?
echo 字符串=%字符串%
goto eof
:error
echo.
echo @PROMPT Invalid input. Invalid characters: $Q $L $G $B$_>
%temp%.\t2.bat
%comspec% /c %temp%.\t2.bat |FIND ":"
goto input
:eof


一个修改文件的更新日期的程序


@echo off
rem 保存系统时间
echo.|date>sysdate.bat
echo.|time>systime.bat
rem
修改系统时间为指定时间,日期为参数一,时间为参数二,文件名为参数三

date %1
time %2
rem 修改文件的时间
copy %3+,,>nul
rem 恢复系统时间
echo date %%4>current.bat
call sysdate
echo time %%3>current.bat
call systime
rem 程序执行完毕
echo Success.
del systime.bat
del sysdate.bat
del current.bat
echo on


PING某个区段内的所有IP的程序

在命令行输入 a.bat 0 1 2 3 4 5 6 7 8 9
,就能显示某区段的所有 IP 地址 192.168.1.0 - 192.168.1.99
,将其中的 echo 改成 ping 就行,其中的 choice 和 if
语句是等待用户判断是否继续,可以删除,但这样中断程序比较麻烦。
CODE: [Copy to clipboard]
--------------------------------------------------------------------------------

@echo off
:redo
if "%1" == "" goto end
for %%a in (0,1,2,3,4,5,6,7,8,9) do echo 192.168.1.%1%%a
choice continue
if errorlevel 2 goto end
shift
goto redo
:end


一个定时器程序


程序中的 CURRENT.BAT
可以更换为自己需要执行的内容。FIND
一句的时间可以根据自己的需要设定,也可用参数%1代替。还可以改为
TIME 改为 DATE 以完成的定期执行的功能。

------------------------------


Quote:
::CURRENT.BAT
@echo off
echo Haha, it's the time to go!!

::TIMER.BAT
@echo off
:start
echo.|time|find "10:30:00">run.bat
choice /c:y /t:y,59 /n>nul
call run.bat
goto start

ASCII汇编代码,延迟精度为0.001秒,适用平台为MS-DOS/Win9x/WinNT。

德国人Herbert
Kleebauer给出了一个通用方案,通过ASCII汇编器间接产生一个sleep.exe程序来实现延迟,这个程序分为DOS和Win两个模块,分别调用DOS系统中断服务和WindowsAPI。
CODE: [Copy to clipboard]
--------------------------------------------------------------------------------

:: Sleep.bat - Sleep/Delay/Wait n seconds
:: Herbert Kleebauer(Germany) - 2005/05/29
:: Modified by Will Sort - 2005/06/02, 07-25
@echo off
echo q | debug>nul
echo
Bj@jzh`0X-`/PPPPPPa(DE(DM(DO(Dh(Ls(Lu(LX(LeZRR]EEEUYRX2Dx=>sleep.com
echo 0DxFP,0Xx.t0P,=XtGsB4o@$?PIyU WwX0GwUY
Wv;ovBX2Gv0ExGIuht6>>sleep.com
echo
T}{z~~@GwkBG@OEKcUt`~}@MqqBsy?seHB~_Phxr?@zAB`LrPEyoDt@Cj?>>sleep.com
echo
pky_jN@QEKpEt@ij?jySjN@REKpEt@jj?jyGjN@SEKkjtlGuNw?p@pjirz>>sleep.com
echo
LFvAURQ?OYLTQ@@?~QCoOL~RDU@?aU?@{QOq?@}IKuNWpe~FpeQFwH?Vkk>>sleep.com
echo
_GSqoCvH{OjeOSeIQRmA@KnEFB?p??mcjNne~B?M??QhetLBgBPHexh@e=>>sleep.com
echo
EsOgwTLbLK?sFU`?LDOD@@K@xO?SUudA?_FKJ@N?KD@?UA??O}HCQOQ??R>>sleep.com
echo
_OQOL?CLA?CEU?_FU?UAQ?UBD?LOC?ORO?UOL?UOD?OOI?UgL?LOR@YUO?>>sleep.com
echo
dsmSQswDOR[BQAQ?LUA?_L_oUNUScLOOuLOODUO?UOE@OwH?UOQ?DJTSDM>>sleep.com
echo
QTqrK@kcmSULkPcLOOuLOOFUO?hwDTqOsTdbnTQrrDsdFTlnBTm`lThKcT>>sleep.com
echo
@dmTkRQSoddTT~?K?OCOQp?o??Gds?wOw?PGAtaCHQvNntQv_w?A?it\EH>>sleep.com
echo
{zpQpKGk?Jbs?FqokOH{T?jPvP@IQBDFAN?OHROL?Kj??pd~aN?OHROd?G>>sleep.com
echo Q??PGT~B??OC~?ipO?T?~U?p~cUo0x>>sleep.com
sleep.com>sleep.exe
echo wait %1 seconds:
sleep.exe %1000
del sleep.com
del sleep.exe


时钟(Clock)

1、暂停(Pause)、延迟(Delay)、等待(Wait)、睡眠(Sleep)

1)for+set+if,时间精度为0.01秒,适用平台为WinNT/2K/XP/2003。


利用for解析变量%time%并存为两个时间点%start%和%now%,再利用set
/a计算两个时间点的时间差,最后用if判断时间差是否达到设定的暂停时间。
CODE: [Copy to clipboard]
--------------------------------------------------------------------------------

@echo off
setlocal enableextensions
echo %time%
call :ProcDelay 200
echo %time%
goto :EOF

:ProcDelay delayMSec_
setlocal enableextensions
for /f "tokens=1-4 delims=:. " %%h in ("%time%") do set
start_=%%h%%i%%j%%k
:_procwaitloop
for /f "tokens=1-4 delims=:. " %%h in ("%time%") do set
now_=%%h%%i%%j%%k
set /a diff_=%now_%-%start_%
if %diff_% LSS %1 goto _procwaitloop
endlocal & goto :EOF

如何删除所有的空目录?


用这个批处理就可以了。
dir /ad/b/s c:\ |sort /r >c:\kill.txt
For /f "tokens=*" %%i in (c:\kill.txt) DO rd "%%i"
del c:\kill.txt

我想用ECHO向另一P批处理文件写入"%~dp0"字符,可是被翻译成路径写入了,而不是该字符本身,不知各位高手是否有办法??
eg:
echo "%~dp0">test.bat

试试:
echo "%%~dp0">test.bat
文件名中的扩展名的判定
7.如何在批处理中判断文件后缀?实现诸如以下的效果。

if "%1" == "*.dll" goto dll
if "%1""=="*.inf" goto inf

1、如果文件名所指的文件是单个文件,且存在这个文件,且其中不包含路径的指定,那么可以使用以下的方案
CODE: [Copy to clipboard]
--------------------------------------------------------------------------------

for %%x in (*.dll) do if exist "%1" goto dll
for %%x in (*.inf) do if exist "%1" goto inf

2、如果文件名所指的文件是单个文件,但是它不存在,且其中不包含路径的指定,那么可以使用以下的方案
CODE: [Copy to clipboard]
--------------------------------------------------------------------------------

if not exist %temp%\_getext_\nul md %temp%\_getext_
echo _getext_> %temp%\_getext_\%1
if exist %temp%\_getext_\*.dll goto dll
if exist %temp%\_getext_\*.inf goto inf

3、如果程序应用环境是NT系列的命令行,且文件名中只有一个分隔主文件名和扩展名的句点,可以使用以下的方案
CODE: [Copy to clipboard]
--------------------------------------------------------------------------------

for /f "delims=. tokens=2" %%x in ("%1") do set _ext=%%x
if "%_ext%"=="dll" goto dll
if "%_ext%"=="inf" goto dll


目录的存在判定

这似乎是个很简单的问题,在我见过的和我编过的绝大部分批处理中,目录判定都使用的是这个经典格式:

if exist directory\nul command argument(s)


可以说,这个技巧的创始者确实对DOS的研究十分深刻,至少他发现了
nul
所代表的设备管理机制与文件管理机制之间复杂而微妙的关系,nul设备与.
和 ..
等一样可以在大部分路径下直接引用而不会产生系统错误。

但是,也正像 .. 不能在根目录下引用(这在NT
CMD中被修改了)一样,nul也有它的局限性。

当我们在 MSDOS7.10 的环境中加载了 DOSLFN
以实现长文件名支持时, DOSLFN 的某些 BUG 会将 \NUL
的引用转义,此时会将文件判定为目录。


Quote:
C:\>echo.>test.txt

C:\>if exist test.txt\nul echo Exist dir "test.txt"
Exist dir "test.txt"

C:\>

如果说这仅仅是doslfn的问题,那么我们可以禁止DOSLFN,然后再将测试阵地转到光盘上。由于光盘具有独特的文件系统CDFS,\NUL的引用失效了,目录仍然无法被识别出来,不过总算不会把文件误判作目录了。


Quote:
E:\>dir /ad /b
BOOT
DOS71

E:\>if exist boot\nul echo Exist dir "BOOT"

E:\>

我们再转到时新的CMD@WinXP中,如果目录名中包含空格,则无法用长文件名识别其存在。


Quote:
C:\>md "my test"

C:\>if not exist "my test"\nul echo Not exist "my test"
Not exist "my test"

C:\>if not exist "my test\nul" echo Not exist "my test"
Not exist "my test"

C:\>

关于目录的存在判定

用 if exist directory\nul command argument(s)
的方法只要目录含有空格无论如何是匹配不正确的。
我实际应用中一般用下面的方法:
CODE: [Copy to clipboard]
--------------------------------------------------------------------------------

md "my test"
cd "my test" &&echo Exist directory "test"
这样会很准确,但也是有缺点的,那就是会进入其目录

Reply all
Reply to author
Forward
0 new messages