|
看到一个逐行显示的批处理代码:
- for /f "delims= eol=" %%i in ('type %1') do (
- set "str=%%i"
- call set "str=%%str:"= %%"
- call :pickup
- )
- pause
- goto :eof
- :pickup
- ping -n 1 127.1>nul
- if "%str:~0,1%"=="=" set "str=〓%str:~1%"
- set /p "=%str:~0,1%"<nul
- set "str=%str:~1%"
- if defined str goto pickup
- echo.&echo.
- goto :eof
复制代码
它的作用是逐行显示一个文本,就是模拟每一行的快速向前推进输出,而不是一下子整行的输出。
先说明一下代码里面的一些语句:
call set "str=%%str:"= %%"
这行语句是将 %%str:"=%% 赋值给 str ,这实际上是 set 的一种增强型表达式,即将“空格”代替文本行中的双引号(具体参考 set /?)。如果你疑问为什么用这么多百分号,那么请参考 call set 的说明《call set 与 变量延迟》。
if "%str:~0,1%"=="=" set "str=〓%str:~1%"
这一条语句的目的是将行中的 = 号换成 〓 ,为什么这么做?
这是因为,逐行推进式的显示,会涉及到不换行的输出,这需要用 set /p "=xxxx"<nul 这种做法,如果直接用 echo 来做,这就会导致换行,而批处理里的 echo 功能却弱于 linux shell 中的 echo,人家可以直接一个 -n 选项不换行。若是用 set /p 来输出等号,似乎找不到什么可行的办法,因为等号在批处理里是个特殊用法的符号,即使你用 ^ 转义字符也不行。那我们如果不想输出这个 〓 符号,而是直接输出原汁原味的 = 符号那该怎么办?直接用批处理,我找不到更加直接的做法,但想到了一个另类的做法:= 符号用一个可执行程序来输出,比如 C 代码就只有一句 printf ("="); 即可。将该比 hello world 还要更小的 C 程序复制到如 D:\ 的根目录下,那么可以有如下代码:
- @echo off
- for /f "delims= eol=" %%i in ('type %1') do (
- set str=%%i
- ::call set "str=%%str:"= %%"
- call :pickup
- )
- goto :eof
- :pickup
- ping -n 1 127.1>nul
- if "%str:~0,1%"=="=" set "str=〓%str:~1%"&D:\Project1.exe>sss.txt&type sss.txt&&set str=%str:~1%&del
- sss.txt&goto pickup
- set /p "=%str:~0,1%"<nul
- set str=%str:~1%
- if defined str goto pickup
- echo.&echo.
- goto :eof
复制代码
上面代码中,project1.exe 就是在命令行中打印 '=' 符号的程序,我们执行这个程序并将输出重定向到一个名为 sss.txt 的临时文件中,然后在用 type 来将其打印,弄完之后再 del 掉该临时文件。需要注意的是,不能 echo 一个 = 符号到一个文本中,那样仍然包含一个换行,而 C 程序是可以控制不包含换行符的输出。
至于除了等号之外的其它特殊符号,该程序是可以处理的。
|
|