返回列表 发帖

批处理读书笔记

最近我对批处理的学习有点感兴趣了,学到了不少东西,以前我以为批处理就是一个单调的黑白世界,但是,当我看到了一些精彩的程序后,才知道原来批处理可以这样,原来黑白世界也精彩。

     精彩实例1--- 弹动的小球:
@echo off&mode con cols=20 lines=29&color 2c
setlocal enabledelayedexpansion
title 弹球-zw19750516
set a=●&set "b= "
:begin
cls&set n=0
set /a lm=%random%%%19,lr=%random%%%2
if %lm% equ 0 (
set z=+
) else (
if %lm% equ 17 (
set z=-
) else (
if %lr% equ 0 (
set z=-
) else (
set z=+
)
)
)
:contin
set "kong="
set /a n+=1,lm%z%=1
for /l %%i in (1,1,%lm%) do set kong=!kong!%b%
set str%n%=%kong%%a%
if %n% equ 30 goto begin
if %lm% equ 0 set z=+
if %lm% equ 17 set z=-
set /p=!str%n%!nul
for /l %%i in (1,1,20) do set /p= <NUL
echo.
goto continCOPY
精彩实例2---跳动的小球
@echo off&setlocal enabledelayedexpansion
mode con: cols=81 lines=30&color 1f
:: code by 随风@bbs.bathome.net 2008/01/03
:loop
for /l %%a in (1 1 40) do (
  if defined sang (
  cls&set /a di-=1
  for /l %%i in (1 1 !di!) do echo.
) else (echo.&set /a di+=1)
  if defined zuo (set ko=!ko:~1!) else set ko= !ko!
  set /p=!ko!●<nul
  for /l %%i in (1 1 80) do ver>nul
  set /p=  <nul
  if not "!ko:~38,1!"=="" set zuo=ok
  if "!ko!"=="" set zuo=&set "ko= "
  if !di! lss 0 set sang=&goto loop
  if !di! geq 29 set sang=ok&goto loop
)COPY
精彩实例3----五彩的世界
@echo off
::输出彩色字符
mode con lines=24 cols=69
set "a= One World !"
set "b= one Dream !"
set "c= 让我们大家一起说"
set "d=︱ bbs.cn-dos.net is our common home!"
set "e= {Author∶jvive︱08-03-31︱Thanks to∶9527}"
set "x= ︱"
set "p=★★★★★★★★★★★★★★★"
set "k="
pushd %tmp%
del/q "%a%?" "%b%?" "%c%?" "%d%?" "%e%?" "%x%?" "%p%?" 2>nul
call:enter 3
call:JV a "%a%" 0
call:JV b "%b%" 0
call:JV c "%c%" 0
call:enter 5
call:JV 0100 0 0
call:JV 040a "%d%" 0
call:JV 040a "%x%" 0
call:JV 0100 000 0
call:JV 040b "%d%" 0
call:JV 040b "%x%" 0
call:JV 0100 000 0
call:JV 0400 "%d%" 0
call:JV 0400 "%x%" 0
call:JV 0100 0 1
call:enter 3
call:JV e "%e%" 0
call:JV 0100 0 1
echo.
call:color
pause>nul&exit/b
rem ---------subprocess--------
:color|一二层第一个色调混合为主色调,最后一个为闪烁停留色调.
for %%a in (0 e)do (
for %%b in (a 1 2 3 4 5 6 7 8 0 c b d f e)do (
call set "k=%%k%%"
call:bak %%a%%b "%p%" 0
))
goto :eof
:JV
:bak
if %3 neq 1 (set/p=%k%"%~2") else echo.>"%~2"
if %0 neq :bak (set k=) else set "k=%k%"
findstr /a:%1 .* "%~2?"
del "%~2?"
goto :eof
:enter
for /l %%a in (1 1 %1)do echo.COPY
看了这些精彩的实例,这个黑白世界变的有点可爱了。然该死的微软,关于批处理的资料说的是那样的含糊,
把批处理弄的象一个黑色的暗箱。让人学习批处理的难度,远远大于学习其它高级语言,正是上贼船容易,熟悉贼性难于上青天,所以高手的经验,就显得特别的重要。

     在这里我将把我看到的一些好的东西记录下来。这样可以防此遗忘。我以后在要找这些东西,我以有个查阅的地方。

------------------NOTE-----------------
---停此shift创建的循环----
@echo off
call:one 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30
goto:eof
:one
echo %5
if %5a==a goto:eof
shift
goto oneCOPY
---------
今天读书时看到了,如何停此由shift构造的循环。以前我还真的不知道,长知识了。
if %5a==a goto:eof

if %3a==a goto:eof

if %8a==a goto:eof

if %5#==# goto:eof
原来是这样停下来的。呵呵

----让变量名动态的变化


[/code]
@echo off
rem 让变量名字动态的变化
set tt=123
for /l %%i in (0 1 10) do (
set tt%%i=%tt%
set tt%%i
set tt%%i=
)
echo ------
set var=123
setlocal enabledelayedexpansion
for /l %%i in (0 1 10) do (
   set /a n+=1
   set var!n!=%var%
   set var!n!
)
echo ------
set tt=123
call:one 1 2 3 4 5 6 7 8 9 10
goto:eof
:one
set tt%1=%tt%
set tt%1
shift
if %1a==a goto:eof
goto one
echo ------
rem 追加值
setlocal enabledelayedexpansion
for /l %%i in (0 1 10) do (
set tt=!tt! %%i
set tt
)
echo ------------------
call:one 1 2 3 4 5 6 7 8 9 10
goto:eof
:one
set tt=%tt% %1
set tt
shift
if %1a==a goto:eof
goto oneCOPY
@echo off
rem 看到两种去掉左面0的方法
set tt=001234
for /f "delims=0" %%i in ("%tt%") do (
echo %%i
)
echo ----
set /a "tt=1001234 %%1000000"
set tt
rem  (1000000+1234)/1000000=1234COPY
精彩实例4----变动的方框
::这一版本的编辑---if exist    Q523066680
@echo off&mode con cols=60 lines=30 &color 0a
setlocal enabledelayedexpansion
set omax=oooooooooooooooooooooooooooooooooooooooo
set kmax=%omax:o= %
set n=4
:a
set /a n+=4
set /a upkh=15-%n%/4,kleft=30-%n%/2,zk=%n%-4,zkh=%n%/2-2
set leftk=!kmax:~0,%kleft%!
set zk=oo!kmax:~0,%zk%!oo
set hang=!omax:~0,%n%!
for /l %%a in (1,1,%upkh%) do echo.
echo.%leftk%%hang%
for /l %%a in (1,1,%zkh%) do echo.%leftk%%zk%
echo.%leftk%%hang%
echo.%n%
for /l %%a in (1,1,2) do ping -n>nul
cls
if %n%==40 set /a n=4
goto aCOPY

[ 本帖最后由 myzwd 于 2009-3-20 19:13 编辑 ]
1

评分人数

set /p 与nul的配合

dos中常用的显示命令是echo,我看到别人用set /p来显示数据,于是就跟着学,特别是把set/p 和nul配合使用
@echo off
set /p=a123a <nul
echo b123bCOPY
结果会显示---a123a b123b
这相当于把前后连了起来。
@echo off
echo a123a111111 & dir^  
d:COPY
这于字符连字号 ^ 的效果一样。
这个符号 ^ 是dos里面的多义词
echo
echo.123COPY
echo后面加一点 可以屏蔽错误信息。
@echo off
rem 3x4矩阵的转置,看了几个帖子,于是我也有了一种冲动,就编写了这个矩阵转置的程序
setlocal enabledelayedexpansion
for /f "tokens=1-4" %%1 in ('more +14 %~s0') do (
set tt=!tt! %%1 %%2 %%3 %%4
)
call:one %tt%
goto:eof
:one
echo %1 %5 %9
shift
if %9.==. goto :eof
goto one
goto:eof
11 12 13 14
21 22 23 24
31 32 33 34COPY
------如何利用findstr把输入的字变为彩色的字----函数应用
@echo off
rem 2009-3-5---findstr让输入的字成为彩色字体的方案
set tt="I LOVE HOME OF BATCH"
call:one %tt%
goto:eof
:one
set /p=    <nul>%1
rem 生存类文本,无扩展名,nul让字符串提前的性质
findstr /a:24 .* "%~n1?"
rem 这里加载类文本 这里的%1指向call:one后的%tt%,代表文件名
rem 利用findstr对于非内容的特定字符会显示彩色的特性,最后显示彩色文本
del %1
rem 删除生存的类文本
set tt=
rem 整体构思是利用了批函数 ,具有参数的要点来设置程序的
echo.
echo.
echo ----下面是对比程序--
set tt="I LOVE HOME OF BATCH"
call:two %tt%
goto:eof
:two
findstr /a:24 .* "%~n1?"
set tt=
rem 上面的代码可以简化如下,这样更能看出本质来
@echo off
call:one 我来了 你好 啊
goto:eof
:one
set /p=>%1
findstr /a:24 .* "%1*"
rem %1始终指向 call:one 后面的字符常量,"%~1*"这里是生存的文件,引号很重要。
rem 没有用nul 就要回车才可以看到文字 冒号可以用这个字符,退格符号删去COPY
@echo off
echo ------采用23416进制数显示彩色字体  实验程序---
findstr /n /a:12 .*   %~s0
findstr /n /a:c24 .*  %~s0
findstr /n /a:24 .*   %~s0
findstr /n /a:120c .* %~s0
echo -----退格符号,删去显示-------
findstr /n /a:12 .*  %~s0
findstr /n /a:c24 .*  %~s0
findstr /n /a:24 .*   %~s0
findstr /n /a:120c .* %~s0
rem 在阴影上3位数,画格子,4位数画竖线,也就是说3位以上的数字就产生花纹。
goto:eof
仗剑江湖  仗剑江湖   仗剑江湖a
仗剑江湖  仗剑江湖   仗剑江湖b
仗剑江湖  仗剑江湖   仗剑江湖cCOPY
最后 color 与findstr可以配合使用


数学计算:findstr的阴影部分是2位hex,共能产生16*16=256种色彩,花纹部分也是2bit的hex 这也有256种。
色彩就这么多,多一种都不可能有。

下面的说明了符号 是如何产生的。
*******************************************************************
1----进入edit
2----按下 ctrl+p ,松开,要松开!这时在edit中什么都看不到
3---接着按下backspace退格键,此时就看到了这个符号
4--保存到记事本中就可以了。


==========================================================
   全屏cmd ----  修改注册表 路径:HKCU\CONSOLe\   FULLSCREEN  VALUE=1(全屏),0(非全屏)


@echo off
echofindstr只显示标签,实现输入彩色字
echo.>中国足球是笑话
findstr /a:0c z* 中国足球是笑话*
del /q 中国足球是笑话
rem cmd将显示的是---红色的--- “中国足球是笑话:”COPY


[ 本帖最后由 myzwd 于 2009-3-19 09:43 编辑 ]

TOP

与楼主有同感!想进一步,可批处理比较全面系统的教程都不知在那里有,看高手的代码,大部分看不懂,又没有解释,批处理想提高真的比学高级语言还难!

TOP

回复 3楼 的帖子

本版有很多教程,不知你看过了哪些?
高手的代码看不懂没关系,哪行不懂就发帖问哪行,自然有热心人给你解释。
我帮忙写的代码不需要付钱。如果一定要给,请在微信群或QQ群发给大家吧。
【微信公众号、微信群、QQ群】http://bbs.bathome.net/thread-3473-1-1.html
【支持批处理之家,加入VIP会员!】http://bbs.bathome.net/thread-67716-1-1.html

TOP

如何插入html代码?

@echo off
::我一直在想如果用dos调用html代码,今天我算是找到方法了2007-3-6 by myzwd。
call:one my.htm
goto:eof
:one
more +9 %~s0>my.htm
start %1
del my.htm
goto:eof
<html >
<head>
<title>myzwd123456</title>
</head>
<body>
<u>中国</u>
<font color=red><marquee>myzwd </marquee></font>
<table width="200" border="1">
  <tr>
    <td>myzwd</td>
    <td bgcolor="#FF00FF"></td>
    <td bgcolor="#99CC00"></td>
    <td bgcolor="#9933FF"></td>
  </tr>
  <tr>
    <td>myzwd</td>
    <td bgcolor="#FF00FF"></td>
    <td bgcolor="#99CC00"></td>
    <td bgcolor="#9933FF"></td>
  </tr>
  <tr>
    <td>myzwd</td>
    <td bgcolor="#FF00FF"></td>
    <td bgcolor="#99CC00"></td>
    <td bgcolor="#9933FF"></td>
  </tr>
</body>
</html>COPY
@echo off
:<!--
rem 我一直在想如果用dos调用html代码,今天我算是找到方法了2007-3-6 by myzwd。
call:one my.htm
goto:eof
:one
more +1 %~s0>my.htm
start %1
del my.htm
goto:eof
-->
<html >
<font color=red><marquee>myzwd </marquee></font>
</html>COPY
其实可以把bat放到html的注释里面,html的注释符号是<!-- 啊啊啊啊-->,dos 的标准注释是rem,顺便指出,符号“::”人们也常拿来注释,但是你试一下,在for里面用会报错的其实"::"这种符号与 ":a 123jk" 是一回事,它应该是子程序的记号。我觉得bat里面还是要尽量用标准的写法l。反过来也可以把html代码放到bat的注释里面。
但这种做法完全是多余的。比如上面这中写法在网页上就多出一个:号。正规的网页多一个冒号也是不可以的。

还有就是html代码码很长,以我编辑网页的经验的话,乱放是很麻烦的事情。加载代码和加载js,vb脚本是一回事情,因为这只不过是在<html>...</html>间再插入代码吧了。

问题:我一直没找到 %~s1 和%~f1的差别在那里,我每次混用给我的感觉都一样,差别在那呢?
@echo off
echo 另类循环 骗骗你让你最后成为死循环 你运行3次试一试
:one
echo I LOVE YOU HOME OF BATCH
set /a n+=1
if %n%==20 goto end
if errorlevel 10 goto one
exit /b 10
:end
echo 循环次数%n%COPY

[ 本帖最后由 myzwd 于 2009-3-12 23:10 编辑 ]

TOP

问题:说真的我根本不知道这个符号是怎么打出来的---退格符号

edit==><ctrl>+p==>退格符
for /f "delims=" %%a in ('%0') do (echo %%a)

TOP

我帮忙写的代码不需要付钱。如果一定要给,请在微信群或QQ群发给大家吧。
【微信公众号、微信群、QQ群】http://bbs.bathome.net/thread-3473-1-1.html
【支持批处理之家,加入VIP会员!】http://bbs.bathome.net/thread-67716-1-1.html

TOP

call控制时间做动画,比较好

@echo off
rem call 运行比for慢,控制时间 动画
color 0c
for /l %%1 in (1 1 5) do (
for /l %%2 in (1 1 100) do (call echo %time%>nul )
call set tt= ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■  
call echo %%tt%%
)
for /l %%1 in (1 1 5) do (
for /l %%2 in (1 1 100) do (call echo %time%>nul )
call set tt= ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■  
call set tt=  %%tt:~2%%
echo.
call echo %%tt%%
)
for /l %%1 in (1 1 5) do (
for /l %%2 in (1 1 100) do (call echo %time%>nul )
call set tt= ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■  
call set tt=      %%tt:~7%%
echo.
call echo %%tt%%
)COPY
call比for慢 这个特性刚好可以做动画的时间控制
@echo off
color 0c
echo  ---callping控制时间的动画效果对比
echo ----ping
for /l %%i in (1 1 5) do (
  set tt=■■■■■■■■■■
  ping -n 2 localhost >nul
  echo %tt%
)
echo ---call
for /l %%i in (1 1 5) do (
  set tt=■■■■■■■■■■
  for /l %%1 in (1 1 100) do (call echo %time%>nul)
  echo %tt%
)
echo ---显见call控制时间具有更大的自由度,特别是ping闪烁的光标要处理COPY

call取值100大概等于ping取2的速度

[ 本帖最后由 myzwd 于 2009-3-7 19:57 编辑 ]

TOP

回复 6楼 的帖子

谢谢 我按你的方法成功了。非常谢谢。

TOP

dos里面居然可以有遮罩---妙

@echo off
echo  ---认识退格键  ""
echo     中国人民解放军WS
echo     中国人民解放军WS
echo     中国人民解放军WS
echo     中国人民解放军WS
echo     中国人民解放军WS
echo     中国人民解放军WS
echo     中国人民解放军WS
echo     中国人民解放军WS
echo     中国人民解放军WS
echo     中国人民解放军WS
echo     中国人民解放军WS
echo ---退格符就是一辆车走的路程,原有的字符就是一条路,
echo     退格符后面的字符就是车,车过了,路还是路。
echo     有的高手把退格符叫---挖土机,形象吧。
echo ********************************
echo ---动画演示退格符-■---
echo *********************************
for /l %%j in (1 1 100) do (call echo %time%>nul)
color 0c
set bs=
for /l %%i in (1 1 10) do (
    for /l %%j in (1 1 200) do (call echo %time%>nul)
    call set bb=%%bs:~%%i%%
    call set tt= 中国人民解放军万岁%%bb%%■人民英雄永锤不朽
    call echo %%tt%%
)
echo 多象flash的遮罩,不过遮罩是遮住的显示,没遮住的不显示,
echo  这里刚好与flash的遮罩功能相反COPY
@echo off
echo ----退格符应用动画---逐渐显示小方块
color 0c
set bs=
for /l %%i in (1 1 120) do (
  set bs=■%bs%■
  for /l %%1 in (1 1 100) do (call echo %time%>nul)
  call set /p=%%bs%%<nul
)
echo --------------
set bs=
for /l %%i in (1 1 200) do (
  set bs=%bs%■
  for /l %%1 in (1 1 100) do (call echo %time%>nul)
  call set /p=%%bs%%<nul
)COPY
上述两段程序只有一字之差,确显示出完全不同的效果。“set bs=■%bs%■ 和set bs=%bs%■”
@echo off
color 0c
set bs=
for /l %%i in (1 1 10) do (
  set bs=%bs%■
  for /l %%1 in (1 1 100) do (call echo %time%>nul)
  call echo %%bs%%
)COPY
程序分析:一切都是nul再作怪。把前面的程序最后一句改成这样:call echo %%bs%%,将得到靠左面的一列
小方块。因为迭代变量是 “bs=方块 退格 方块”,退格后bs的值就只能是 永远是一个方块。


----------------两个迭代变量------------------------------
tt=%tt%123   --------结果是:123,123123,123123123.。。。。。。
tt=%tt%123 --------123,12123,1212123,121212123......
--------------两个迭代显示--------------------------------
echo  %tt%123
set/p=%tt%123<nul  
----------------------------迭代当然离不开循环了。

-------------------------------------如何在左面插入空格
@echo off
echo 在■ 的左面插入10个空格
cls
setlocal enabledelayedexpansion
color 0c
for /l %%i in (1 1 10) do (
set tt=0!tt!
)
set tt=%tt%
set tt=%tt:0= %
echo !tt! COPY
其实插入空格最好的办法是利用set变量
set space=     ----这样是不行的
set space=“ ” 这样还是不行的
要这样:
set "space=   "
要10个空格就循环吧
for /l %%1 in (1 1 10) do (call set "space= %%space%%")COPY
@echo off
echo ---匀速向左运动,显示2个整行
set tt=
color 1d
for /l %%i in (1 1 78) do (
  for /l %%1 in (1 1 100) do (call echo %time%>nul)
  set tt=■■
  call set/p=%%tt%%<nul
)
echo.
echo ---匀速向左运动,显示2个整行 英文
set tt=
color 1d
set tt=
for /l %%i in (1 1 158) do (
  for /l %%1 in (1 1 50) do (call echo %time%>nul)
  set tt=AA
  call set/p=%%tt%%<nul
)
echo.  
echo ---匀速向左运动,显示2个整行 中英文混合
set tt=
color 1d
set tt=
for /l %%i in (1 1 156) do (
  for /l %%1 in (1 1 50) do (call echo %time%>nul)
  set tt=A■
  call set/p=%%tt%%<nul
)
echo.  COPY
@echo off
echo ---迷失的A
set tt=
color 1d
set tt=
for /l %%i in (1 1 115) do (
for /l %%1 in (1 1 50) do (call echo %time%>nul)
set tt=■A
call set/p=%%tt%%<NUL
)
echo.
echo ----
set tt=
color 1d
set tt=
for /l %%i in (1 1 120) do (
for /l %%1 in (1 1 50) do (call echo %time%>nul)
set tt=■A
call set/p=%%tt%%<NUL
)COPY
这的放法是个细节,要想成为整行,就在这里下功夫。循环终值=(40-1)*行数,英文 循环终值=(80-1)*行数
混合 循环终值=(80-2)*行数 迷失的A例外--循环终值=40*行数 或 循环终值=40*行数-1(显示A)
@echo off
echo ---居中显示
color 1d
set tt=
set ss=
for /l %%i in (1 1 16) do (
  call set ss=%%ss%%0
)
call set ss=%%ss:0= %%
call set /p=%%ss%%<nul
for /l %%i in (1 1 21) do (
  for /l %%1 in (1 1 50) do (call echo %time%>nul)
  call set tt=■■
  call set /p=%%tt%%<nul
)
echo.COPY
@echo off
echo ---退格符完成简易向右运动
cls
echo.&echo.&echo.
color 1d
set tt=
set ss=
set bs=
for /l %%i in (1 1 78) do (
  call set ss=%%ss%%0
)
set ss=%ss:0= %
set /p=%ss%<nul
for /l %%i in (1 1 15) do (
  for /l %%1 in (1 1 100) do (call echo %time%>nul)
  call set  bs=%%bs%%
  call set tt=%%bs%%■
  call set /p=%%tt%%<nul
)
echo.
echo   原理是利用78个空格基本铺满第一行,给小方块留下2byte的位置,
echo   利用退格符相当于是它后面字符走的路程的原里,让退格符逐渐增加,即字符的路程加大
echo  这样就实现了反方向运动,为了好记忆我自己把退格符的这种性质叫退格符的--------
echo  路程原理  ,如果退格符后面没字符,这个路程也就不起作用了COPY

[ 本帖最后由 myzwd 于 2009-3-9 16:19 编辑 ]

TOP

退格符

二点体会:
退格之后,处于改写状态,二个英文字符相当一个汉字。
在复合句中,call有延迟变量的功能。

TOP

很好的笔记,学习了!

TOP

回复 11楼 的帖子

一个汉字=2个英文字,但是从上面的实例可以看出,退一格就是一遮住一个字符,不管它是中文还是英文。
另外 关于call 的延迟性的理解,我个人认为可以理解得简单点,就是cmd在解释语句时,遇到call就会对程序再解释,以补充不足的数据,以完成数据匹配,最后实现对程序的执行,最终以,这样就实现了数据的动态变化。微软的bat是一个黑箱,想多了反而自找麻烦。呵呵

今天研究了本论坛两大高手的代码,觉得高手的代码就是不一样。长知识了。
@echo off
rem ----向右运动
setlocal enabledelayedexpansion&color 1d
for /l %%i in (40 -1 1) do (
    for /l %%1 in (%%i ,-1,1) do (
      set /p= <nul
    )
   
    set /p=■<nul
    for /l %%1 in (1 1 50) do (echo.>nul)
    cls
)COPY

[ 本帖最后由 myzwd 于 2009-3-9 15:37 编辑 ]

TOP

回ls

一个格退格符就向后退一个字符的位置,退格符后面的内容就从这个位置开始输出,并改写此位置后面的原有内容,二个英文字母改写一个汉字,没被改写的原样输出。难道你不认为是这样么?

TOP

只有二种方法能实现变量的延迟
1、setlocal enabledelayed
2、call
难道你不认为这样么?

TOP

返回列表