[新手上路]批处理新手入门导读[视频教程]批处理基础视频教程[视频教程]VBS基础视频教程[批处理精品]批处理版照片整理器
[批处理精品]纯批处理备份&还原驱动[批处理精品]CMD命令50条不能说的秘密[在线下载]第三方命令行工具[在线帮助]VBScript / JScript 在线参考
返回列表 发帖
这个题倒是让我想起了如何用bat操作数组。本想模拟几个数组处理函数,还没设计好。
  1. @echo off
  2. setlocal enableDelayedExpansion
  3. set num=100
  4. set class_num=10
  5. for %%a in (A B C D) do (
  6. call :getRanArr %%a 1 %num%
  7. set %%a=!%%a:#=%%a!
  8. )
  9. set backdoor1=B60
  10. set backdoor2=C49
  11. set target1=3
  12. set target2=8
  13. set /a cnt = num / class_num
  14. for /l %%a in (1 1 %class_num%) do (
  15. for %%x in (A B C D) do (
  16. for /l %%i in (1 1 %cnt%) do (
  17. for /f %%A in ("!%%x!") do set class_%%a=!class_%%a! %%A& set %%x=!%%x:*%%A =!
  18. )
  19. )
  20. echo class %%a:
  21. echo !class_%%a:~1!
  22. echo;
  23. if /i "!class_%%a:%backdoor1%=!" neq "!class_%%a!" set postion1=%%a
  24. if /i "!class_%%a:%backdoor2%=!" neq "!class_%%a!" set postion2=%%a
  25. )
  26. echo yesterday: %backdoor1%=%postion1%, %backdoor2%=%postion2%
  27. echo;
  28. call :go_backdoor 1 //后来加的
  29. call :go_backdoor 2
  30. echo;
  31. pause
  32. exit /b
  33. :go_backdoor //^_^//
  34. set backdoor=!backdoor%1!
  35. set postion=!postion%1!
  36. set target=!target%1!
  37. set class_%postion%=!class_%postion%:%backdoor%=...!
  38. set class_%target%=!class_%target%! %backdoor%
  39. rem catch a scape-goat
  40. set level=%backdoor:~0,1%
  41. set str=!class_%target%:*%level%=!
  42. for /f %%a in ("!str!") do set scape-goat=%level%%%a
  43. set class_%target%=!class_%target%:%scape-goat% =!
  44. set class_%postion%=!class_%postion%:...=%scape-goat%!
  45. echo new class %postion%:
  46. echo !class_%postion%!
  47. echo new class %target%:
  48. echo !class_%target%!
  49. echo;
  50. goto :eof
  51. :getRanArr arrName start end [step] //不对参数作合法性检查,coder自己保证参数的正确性
  52. setlocal enableDelayedExpansion
  53. set /a "start=%2, end=%3, step=(^!(%40/10))|(%40/10)"
  54. set "_ret="
  55. for /l %%a in (%start% %step% %end%) do set #_!random!_%%a=1
  56. for /f "tokens=2 delims=#_=" %%a in ('set #_') do set _ret=!_ret! #%%a
  57. endlocal & set %1=%_ret:~1%
  58. goto :eof
  59. rem ToDo: find time to implement these function
  60. rem How about letting bat operate array? Crazy or not?
  61. :shuffle arrName len cnt //洗牌
  62. :slice arrName start [end] //返回一个数组的一段(指定起停)
  63. :sliceLen arrName start length //返回一个数组的一段(指定长度)
  64. :splice arrName start deleteCount //从一个数组中移除一个或多个元素,如果必要,在所移除元素的位置上插入新元素,返回所移除的元素
复制代码
命令行参考:hh.exe ntcmds.chm::/ntcmds.htm
求助者请拿出诚心,别人才愿意奉献热心!
把查看手册形成条件反射!

TOP

我的思路竟然和随风基本上是一样的!

代码有点啰嗦,最近在学习编程规范。
命令行参考:hh.exe ntcmds.chm::/ntcmds.htm
求助者请拿出诚心,别人才愿意奉献热心!
把查看手册形成条件反射!

TOP

  1. @echo off
  2. setlocal enableDelayedExpansion
  3. set amount=100
  4. set types=A B C D
  5. set slices=10
  6. set special=B-60-3 C-49-8
  7. for /l %%a in (1 1 %amount%) do set arr=!arr! #-%%a
  8. for %%i in (%types%) do (
  9.     set "%%i=!arr:#=%%i! " 后面特意加了空格
  10.     set /a amount_%%i=amount
  11.     for /l %%a in (1 1 %slices%) do set /a num_%%i_%%a = amount / slices
  12. )
  13. for %%a in (%special%) do (
  14.     for /f "tokens=1,2,3 delims=-" %%i in ("%%a") do (
  15.         set %%i=!%%i: %%i-%%j = !
  16.         set /a amount_%%i -= 1
  17.         set /a num_%%i_%%k -= 1
  18.     )
  19. )
  20. for %%i in (%types%) do (
  21.     set #=!%%i!
  22.     set /a left = amount_%%i
  23.     for /l %%a in (1 1 %slices%) do (
  24.         for /l %%n in (1 1 !num_%%i_%%a!) do (
  25.             set /a ran = !random! %% left + 1
  26.             set $=!#!
  27.             for /l %%x in (1 1 !ran!) do set $=!$:* =!
  28.             for /f %%x in ("!$!") do set item=%%x
  29.             set slices_%%a=!slices_%%a! !item!
  30.             for %%x in (!item!) do set #=!#: %%x = !
  31.             set /a left -= 1
  32.         )
  33.     )
  34. )
  35. for %%a in (%special%) do (
  36.     for /f "tokens=1,2,3 delims=-" %%i in ("%%a") do set slices_%%k=!slices_%%k! %%i-%%j
  37. )
  38. for /l %%a in (1 1 %slices%) do echo class %%a:& echo !slices_%%a!& echo;
  39. echo;
  40. pause
  41. exit /b
  42. :shuffle arrName len cnt //洗牌
复制代码
适应每个数组元素名字未知(开始生成一个数组是当没有给出时手动生成)、长度不定(当然总长度必须小于单个变量最大长度8k)
命令行参考:hh.exe ntcmds.chm::/ntcmds.htm
求助者请拿出诚心,别人才愿意奉献热心!
把查看手册形成条件反射!

TOP

为什么大家都觉得我是计算机专业的呢?

编程规范要求一行上最好只放一条语句(其实大家都懂的)

set /a 后面加空格是可以的而且是应该的,以突出运算逻辑和提高可读性。它和set进行字符串赋值有所不同,对于后者多余的空格也会成为变量名/值的一部分。

变量命名应该尽量做到短小而又有所含义(能做到见名知义就更好了),不要全用毫无意义的a、b、c之类的,当然有一些习惯性用法,比如n表示数量,i用于for循环变量等。

语句对齐问题:我发现做到并坚持这一原则的人真的很少。批处理就算再简单,基本的结构还是有的,不要一味为了简洁就无视它。
复合语句收尾的括号应与关键字在同一列上对齐(主要就是if、for,因为开始的括号不能另起一行放在行首,否则就与它对齐了),内部子语句应该适量缩进(一般4个空格,多数编辑器都是这个默认值,不用你多敲)。当子语句只有一两个且较简单,也可以省去括号(在bat中不反对大家这么做)。

正确、高效、易读,最容易做到的就是易读,却往往最难被人做到,悲乎哀哉!就算代码功能上不怎么样,变量名称、基本意思、流程结构应该写清楚呀,起码能让人看得懂。(terse的代码一向高效,但我一般都没怎么看过,感觉太“难看”了^_^)
命令行参考:hh.exe ntcmds.chm::/ntcmds.htm
求助者请拿出诚心,别人才愿意奉献热心!
把查看手册形成条件反射!

TOP

回复 39楼 的帖子

看36楼的代码,你觉得哪里头疼呢?

代码功能和技巧原理可能不大懂,需要相当的基础和积累才行。但代码格式、基本结构应该容易看懂吧(少数风格迥异的牛人除外,只看三两遍和没看一样)
比如一行句子是什么结构、怎么断句、主体命令是什么,for循环是哪一种、循环体里面有哪些子句,if语句的条件分支是怎样的,从哪里到哪里、是什么逻辑关系;总之大体框架应该读能出来。

试比较35楼的
set /a n=!random!%%_%%a*4
和36楼的
set /a ran = !random! %% left + 1

新手对上面那句,可能很难明白(当然结合代码是必须的,可是对新手还是很难);但下面那句就不一样了(当然本身就简单一点)
命令行参考:hh.exe ntcmds.chm::/ntcmds.htm
求助者请拿出诚心,别人才愿意奉献热心!
把查看手册形成条件反射!

TOP

那就不是易读性的问题,而是技巧性的问题。
我说过,需要相当的基础和积累才行。

set的这个用法你不会,说明你的基本功还不够,对常用命令都不熟。
set /?
    SET P
会显示所有以字母 P 打头的变量

而set /a进行数学运算时,“您可以使用环境变量值做计算而不用键入那些 % 符号来得到它们的值”
据此分析set /a n=!random!%%_%%a*4
断句一下就是set /a n = !random! %% _%%a * 4
前面的%%是求余运算符(在bat中要写成两个,预处理机制,原理和理论知识),!random!加了!符号,因为它是一个特殊的变量,不是我们手动定义的,而是系统提供的动态环境变量,所以要使用!!来得到其值。而_%%a就是的!_%%a!省去!的形式,只是这个展开过程稍微多一步:先由for展开%%a的值,与_拼接后整个成为一个变量名,再由set得到该变量对应的值。
命令行参考:hh.exe ntcmds.chm::/ntcmds.htm
求助者请拿出诚心,别人才愿意奉献热心!
把查看手册形成条件反射!

TOP

返回列表