3.通用性篇
代码的通用性是衡量代码价值的重要标准之一,一个不考虑通用性的代码,可能产生不可预料的致命后果。
当然通用是相对的,我们所谓的通用,一般是在常见环境下的通用,再通用的代码也有它不通用的环境。
3.1 要考虑环境的差别
在不同系统环境下,代码的结果是有差异的,所以一般要尽量选用通用性最强的代码。
【code1】
- timeout /t 3 /nobreak
- choice /c yn
- if %errorlevel%==1 set /p= test<nul
- ::延时 3 秒,等待用户输入,如果为 y 则不换行输出 " test"
- ::在 xp 以下不自带 timeout.exe,而 choice.exe 在 xp 中也不是默认配置,而在 xp 以上的系统中,set /p 会忽略提示语句中为首的半角空格。
复制代码
【code2】
- ping 127.1 >nul
- set /p input=[y,n]?
- if %errorlevel%==y set /p=@ test<nul
- ::为了兼容 xp,这里用 ping 代替 timeout 进行延时,而用 set /p 代替 choice,并且在 set /p 中加入退格符,避免空格开头在 vista/win7 下出错
复制代码
3.2 要考虑输入中含有特殊字符
【code1】
- @echo off&setlocal enabledelayedexpansion
- for /f "delims=" %%a in (1.txt) do (
- if !last! neq %%a echo %%a
- set last=%%a
- )
- ::排除重复的相邻行,看似简单,但却隐含了很大的漏洞,如果 1.txt 中存在以 ; 为首的行将被忽略(默认情况下 eol=;),另外,假如某一行包含 ! 结果将出错
复制代码
【code2】
- @echo off
- for /f "delims=" %%a in ('findstr /n . 1.txt') do (
- rem 用 findstr /n 给输入加行号,防止 ; 开头的行被忽略
- set str=%%a
- setlocal enabledelayedexpansion
- rem 在将行内容设为 str 变量后再打开变量延迟,避免引用 %%a 时由于其中存在 ! 号而出错
- if !last! neq !str:*:^=! echo !str:*:=!
- rem 当上一行内容与当前行内容(去掉行号后的)不相同则输出当前行
- for /f "delims=" %%b in (""!str:*:^=!"") do endlocal&set last=%%~b
- rem 关闭变量延迟,并通过 for /f 保留 !str:*:=! 的值赋予 last 变量,并通过加引号、去引号的技巧再次防止以 ; 为首的行被忽略
- )
- ::排除重复的相邻行,虽然比较复杂繁琐,但是在不明背景的情况下,必须要考虑到方方面面
- ::这种严谨的态度是出于周全的考虑,一个人的水平从他代码是否严谨就可以略窥一二。
复制代码
3.3 考虑到命令与输入的细节特征
这和 3.2 的内容有部分重复,在此只讲不重复的部分
【code1】
- for /l %%a in (0 1 9) do set str=!str:%%a=!
- ::去除str变量中所有数字,但是当str变量中只有数字且没有9的时候将出错。
复制代码
【code2】
- set str=9!str!
- for /l %%a in (0 1 9) do set str=!str:%%a=!
- ::给变量附加一个 9,避免当str变量已经为空时仍进行变量替换,在最后一次替换中,这个多余的字符也将被去除
复制代码
【code1】
- for %%a in (*《*》*.txt) do (
- for /f "tokens=2 delims=《》" %%b in ("%%a") do echo %%b
- )
- ::显示txt文件名中《》之间的部分,仍存在跳过以;开头的内容的缺陷,不过这个可以将eol设为文件名中不可能出现的字符来解决
- ::比较大的问题是碰到以《为首的文件时会截取错误的部分
复制代码
【code2】
- for %%a in (*《*》*.txt) do (
- for /f "tokens=2 delims=《》" %%b in ("@%%a") do echo %%b
- )
- ::解决方法也很简单,就是在%%a前加上任意不含分隔符的内容,这样无论原文件名是否以《开头,《之前总是有一节。
复制代码
|