Board logo

标题: [转贴] 浅谈批处理脚本的编写 - 2.简洁篇 [打印本页]

作者: HAT    时间: 2011-12-17 13:58     标题: 浅谈批处理脚本的编写 - 2.简洁篇

2.简洁篇
  代码的执行效率是一方面,编写耗时也十分影响代码价值高低,假如花费大量时间写个一次性脚本,写代码比手工操作还慢,那么写代码的意义就很小了。
  同时,简洁的代码也减少了预处理耗时,所以简洁能提升编写效率、执行效率。
  在不需顾虑执行效率的条件下,我们可以遵循几个大概的原则:

2.1 能合并的就合并
  这是废话,不过废话往往是真理
【code1】
  1. set a=1
  2. set b=2
  3. set c=3
  4. ::用三个 set 分别将 a b c 赋值为 1 2 3
复制代码

【code2】
  1. set /a a=1,b=2,c=3
  2. ::用一个 set /a 来一次性赋三个值
复制代码

【code1】
  1. if %1==a (
  2.    if %2==b (
  3.       echo a b
  4.    ) else echo 参数有误
  5. ) else echo 参数有误
  6. ::用 if 嵌套判断两个参数是否都为指定值
复制代码

【code2】
  1. if %1^&%2==a^&b (
  2.    echo a b
  3. ) else echo 参数有误
  4. ::将两个 if 合并为一个
复制代码


2.2 学会使用参数
  不可否认,虽然 call 与外部命令的效率低于大部分内部命令,但是它们往往是比较简洁的选择,许多时候,我们可以利用 cmd /c 或 call 改变参数来实现简写。
【code1】
  1. @echo off&setlocal enabledelayedexpansion
  2. call :test time
  3. pause&exit
  4. :time
  5. echo !%1!
  6. ::传递参数 %1 为 time,再显示以 %1 的内容为名的变量值
复制代码

【code2】
  1. %1@cmd /q/v/c %0 : time
  2. echo !%2!
  3. pause
  4. ::用一个 cmd 实现关闭回显、打开变量延迟、替代 call 来修改来传递参数
复制代码


  再举一个例子,看如何实现输出多个字符所有不重复的排列组合:
【code1】
  1. @echo off&setlocal enabledelayedexpansion
  2. set/p s=请输入,用一个空格分开:
  3. echo %time%
  4. set f1=a.txt
  5. set f2=b.txt
  6. >!f1! echo !s:~,1!&set s=!s:~1!
  7. set len=1
  8. for %%a in (%s%) do (
  9.     (for /f %%b in (!f1!) do (
  10.         set tmp=%%b
  11.         for /l %%c in (0,1,!len!) do echo !tmp:~,%%c!%%a!tmp:~%%c!
  12.     ))>!f2!
  13.     set t=!f1!
  14.     set f1=!f2!
  15.     set f2=!t!
  16.     set/a len+=1
  17. )
  18. echo %time%
  19. start %f1%&del/f %f2%
  20. pause
  21. ::代码修改自 wankoilz 的代码,这是多个方案中最高效的变量偏移方案
复制代码

【code2】
  1. @echo off
  2. call:perm "a b c xy z"
  3. pause
  4. :perm <"c1 c2 ..."> // code by plp
  5. setlocal enabledelayedexpansion&set "s=%~1 "
  6. if "!s: =!" == ""  (echo %~2)else for %%b in (%~1)do call:perm "!s:%%b =!" "%~2 %%b"
  7. endlocal&goto:eof
  8. ::修改自 plp626 的超短方案,用 call 传递参数引用函数的特性进行迭代,实现输出所有排列组合,十分精彩
复制代码



2.3 提高代码的重复利用率
  要想简化代码,就要充分榨取代码的剩余价值,让 cmd 吃更少的草,干更多的活。
2.3.1 内联函数
  (批处理函数的高效另类应用(免call的哦!):http://bbs.bathome.net/viewthread.php?tid=5861)
  链接中有详细论述,在此仅举实例:
【code1】
  1. for /l %%a in (1 1 9) do (
  2.    for /l %%b in (0 1 9) do (
  3.       for /l %%b in (0 1 9) do echo %%a-%%b-%%c
  4.    )
  5. )
  6. ::输出 100 到 999 之间的数,两位之间以 - 间隔
复制代码

【code2】
  1. set "函数=for /l %%a in (0 1 9) do "
  2. %函数:0=1% %函数:a=b% %函数:a=c% echo %%a-%%b-%%c
  3. ::将 for 语句设为变量,需要时取用,并可依据实际需求通过变量替进行微调
复制代码

2.3.2 模块化
【code1】
  1. @echo off
  2. for /r c:\ %%a in (*.txt) do echo %%a
  3. for /r d:\ %%a in (*.txt) do echo %%a
  4. for /r e:\ %%a in (*.txt) do echo %%a
  5. for /r f:\ %%a in (*.txt) do echo %%a
  6. pause
  7. ::遍历 c: d: e: f:,获取所有非隐藏属性 txt 文本名称。
复制代码

【code2】
  1. @echo off
  2. for %%a in (c d e f) do call :dir %%a
  3. pause&exit
  4. :dir
  5. for /r %1:\ %%a in (*.txt) do echo %%a
  6. ::通过模块化实现反复调用代码的目的
复制代码



2.4 挖掘命令的“批处理”能力
  在效率篇的 1.3.2 中有相关实例,所以这里就不再说了。
作者: cjiabing    时间: 2011-12-20 23:28

支持简洁!
所谓简洁,一是代码的可读性强,一看就知道是什么了。二是代码的效率高,每个代码都是很必要的,而不是可无可有的。当然,还应包括第三个:思想的简洁,能通过简短的代码来实现强大的功能。




欢迎光临 批处理之家 (http://bathome.net./) Powered by Discuz! 7.2