Board logo

标题: [文本处理] 求助:请帮忙解释下数字按降序排列批处理代码全部构成及SET用法 [打印本页]

作者: rdctgvf    时间: 2014-12-24 10:49     标题: 求助:请帮忙解释下数字按降序排列批处理代码全部构成及SET用法

~不理解为什么这段代码能把一个文本里面的数字按降序排列
怎么做到的,求大神解释下里面代码的具体意义和 set _ 使用
  1. @echo off&setlocal enabledelayedexpansion
  2. for /l %%i in (1,1,80) do set "kong=!kong!#"
  3.   for /f %%i in (c:\1.txt) do (
  4.     set "str=%%i%kong%"
  5.     set "a=!str:~,80!"
  6.     set "a=!a:%%i=!"
  7.     set "_!a!%%i=a"
  8.                                          )
  9.   for /f "delims==_" %%i in ('set _') do (
  10.     set "str=%%i"
  11.     echo !str:#=!
  12.                                         )
  13. pause
复制代码

作者: yiwuyun    时间: 2014-12-24 12:47

有点意思,巧妙利用了set操作的按序排列变量的功能。
作者: shelluserwlb    时间: 2014-12-24 13:11

本帖最后由 shelluserwlb 于 2014-12-24 13:27 编辑

这段代码首先设置了一个具有80个井号的kong变量,然后再利用这个kong给每行字符串都生成一个诸如 _###1254585这个的变量(这些变量的值相同(=a),变量名的总长度也相同)。然后利用set命令的特点显示输出所有开头包含_的变量名。
作者: 慕夜蓝化    时间: 2014-12-24 13:39

文档中若含有_则无法显示完全。
并且某些行并没有被输出,其实我没看懂他这样写的目的 >_<
一连用了那么多set,给个注释也好啊。。。
作者: shelluserwlb    时间: 2014-12-24 14:00

本帖最后由 shelluserwlb 于 2014-12-24 14:10 编辑

第1个for /f   
1.取出文件中的一行(%%i)与kong变量合并生成变量str
2.截取str变量的前80个字符生成变量a
3.删除变量a中的%%i(a中只剩下 若干个#号)
4.将_和a变量和%%i的内容组合变量名并赋值为a   
这段代码执行完毕后,就会生成20个(假如文本有20行)如 _###2525.....252、 _#####969...1544这样的变量,这些变量的变量名长度都相同,且值也相同。
后面就是输出,相信大家都看得懂。
以下是要求按每行数据从小到大进行排序输出的txt文件:
2928326128601232462131283250710027308938740594716691200992050511576
5352129649530193383124730478244772348721985707222557212265817305
217141333532296179938475175265792931789219830308392472584606305
2371620291160322081050531817416284225477019123161801285941026814244
283929972304551060318886921731765136928849135391662294051194618754
1809165929787147057932949630411324311737224509104016550662932273
27396236084901303873154718299242931819623155304661177528921164510335
254221462410491137971033914630292752245114969186002809930190939425
1085287492160525651862932475207612387312368408826675135332406418337
2567810118246621010283281198810903279355871571118961177731143829148
23727111515524141721964179351992331180134926914198081871053303186
378579502856625703213542353218420835730692264021219729654278515442
30215186011014395001656818458819061824708536511543271701327524725
223702764213159156022932717903282522044350522584222768193271431422354
3079720530119542370417125702274761144023302102641160114921224469221
15642298214000242538839193816839550322381321993212316517861828002
13042178002978222022331319116624809338275899045263351248023569
11252165681825711849278422768716060438517976169102391532289954712000
105084292396529699311371735329685626410510259482788519645152723476
29674179062831103792824121564178225289202161443911094228581583531951

作者: 慕夜蓝化    时间: 2014-12-24 14:34

回复 5# shelluserwlb


第一个for认真套取的话还是能看懂的,原来想不懂,他是怎么用来输出的,刚刚测试了一下,没想到for /f 能够直接提取 "set  _"
中 以_开头的变量名其中的数据,还是第一次看到这种写法。
作者: rdctgvf    时间: 2014-12-24 16:23

回复 2# yiwuyun


    set操作的按序排列变量 求指点!
作者: rdctgvf    时间: 2014-12-24 16:25

回复 3# shelluserwlb


    "然后利用set命令的特点显示输出所有开头包含_的变量名。"
    求大神指点 “set命令的特点” 和 set _ 的具体含义
作者: rdctgvf    时间: 2014-12-24 16:30

回复 5# shelluserwlb


    求大神: 指点 “set _”的这样的写法,还有为什么能排序,上面的高手说是 SET的特性 求解释
作者: shelluserwlb    时间: 2014-12-24 19:17

本帖最后由 shelluserwlb 于 2014-12-24 19:53 编辑
  1. @echo off
  2. set "_**25-23=th"
  3. set "_**45*87=th"
  4. set "_***6538=th"
  5. set "_**908#7=th"
  6. set "_**11-23=th"
  7. set "_**858+6=th"
  8. set "_****4*5=th"
  9. set "_***1238=th"
  10. set _
  11. pause
复制代码
如上述代码 (所有变量的变量名长度均相同,值也相同):以变量名的第1个字符的数量进行排序(星号越多显示越靠前),当第一个字符的数量相同时再以第二字符进行比较,...以此类推. 而当遇到数字比较时,它会对连续的数值进行比较(数值越小显示越靠前)。  
所以上述代码运行的结果是:
_****4*5=th
_***1238=th
_***6538=th
_**11-23=th
_**25-23=th
_**45*87=th
_**458+6=th
_**908#7=th
请按任意键继续......
作者: Batcher    时间: 2014-12-24 21:55

回复 10# shelluserwlb


以变量名的第1个字符的数量进行排序

这个说法不是很严谨,它无法解释为什么2个#排在5个*前面。
  1. @echo off
  2. set "_##12345=th"
  3. set "_**25-23=th"
  4. set "_**45*87=th"
  5. set "_***6538=th"
  6. set "_**908#7=th"
  7. set "_**11-23=th"
  8. set "_**858+6=th"
  9. set "_****4*5=th"
  10. set "_***1238=th"
  11. set _
  12. pause
复制代码

作者: rdctgvf    时间: 2014-12-25 09:36

回复 10# shelluserwlb


   
    嗯~ 首先感谢亲的回复,非常感激,然后就是像管理员说的那样,如果是按亲说的那样,按字符长度(长度越长)越优先排列,
是无法解释2个# 和 5个* 为什么2个# 排在 5个* 前面的,但是如果是同一种字符的话,亲的说法就说得通,但是如果多个变量中
参杂的字符不一样的话,结果就会出错!
作者: DAIC    时间: 2014-12-25 10:19

回复 12# rdctgvf


    是按照ASCII排序的
作者: rdctgvf    时间: 2014-12-25 11:28

回复 13# DAIC


感谢亲的指导。刚刚去尝试了,果然是按ASCII排序的,声明的变量名称中,同长度,不同字符的情况下,优先字符对应

的ASCII十进制值排序,然后就是不同长度,单一且同一种字符相同的情况下,字符长度越小的优先级越高 (升序排列)

但是我发现一个问题,就是在单一且同一种字符相同的情况下在变量末尾加入1-9个数字中任意的一个数字,就变成按长度越长的优先排列了 (降序排列)

很神奇 - -!
作者: shelluserwlb    时间: 2014-12-25 12:53

本帖最后由 shelluserwlb 于 2014-12-25 13:06 编辑

回复 14# rdctgvf
批处理果然很神奇,但就set这一个命令就够我们讨论研究半天的了。
作者: DAIC    时间: 2014-12-25 13:40

回复 14# rdctgvf


在单一且同一种字符相同的情况下在变量末尾加入1-9个数字中任意的一个数字,就变成按长度越长的优先排列了 (降序排列)

不知道你想表达什么意思,能把代码发出来看看吗?
作者: rdctgvf    时间: 2014-12-25 13:51

回复 15# shelluserwlb

嗯  谢谢大家的指导,非常感激! 现在在大家的指导下,基本知道了
   
这个代码的写法,和set 命令另外的一种 用法 和 特性
作者: rdctgvf    时间: 2014-12-25 14:00

回复 16# DAIC


首先,感谢亲的回复,我只是想表达在大家的指导下,我慢慢明白了这段代码的用法

因为当时我需要批处理做一个排序输出的功能,无意当中就看到了这个代码,当时的我

不理解为什么用for /f 来提取 "set _" 并且输出的,因为当时的我不知道 set 还可以这样来用

所以,我希望亲如果可能的话,能够给我解释下 set 还能输出变量名称的具体用法
作者: DAIC    时间: 2014-12-25 20:40

回复 18# rdctgvf


在单一且同一种字符相同的情况下在变量末尾加入1-9个数字中任意的一个数字,就变成按长度越长的优先排列了 (降序排列)

我的问题是,你如何得出上面这个结论的?




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