[新手上路]批处理新手入门导读[视频教程]批处理基础视频教程[视频教程]VBS基础视频教程[批处理精品]批处理版照片整理器
[批处理精品]纯批处理备份&还原驱动[批处理精品]CMD命令50条不能说的秘密[在线下载]第三方命令行工具[在线帮助]VBScript / JScript 在线参考
返回列表 发帖

[文本处理] 如何获取相同IP段中C段(第三段)的最小值和最大值并按指定格式输出?

本帖最后由 pcl_test 于 2016-3-3 21:37 编辑

9.79.12.0
9.79.116.0
9.79.219.0
9.79.221.0
9.79.222.0
149.80.1.0
149.80.42.0
149.80.144.0
149.80.249.0
119.189.73.0
119.189.74.0
119.189.82.0
119.189.84.0
119.189.96.0
119.189.99.0
119.189.84.0
119.189.96.0
119.189.199.0
119.189.255.0

我只会用%%I %%J   %%K转换0或255
求大神写个代码     取C段的最小值和最大值 转换成这种格式
转换成
9.79.12.0-9.79.222.0
149.80.1.0-149.80.249.0
119.189.73.0-119.189.255.0
先谢了
1

评分人数

  1. """
  2. IP段整理成a.b.c.0-a.b.c.255的格式.py
  3. http://bbs.bathome.net/thread-31568-1-1.html
  4. 2016年3月3日 02:15:42 codegay
  5. """
  6. import pprint
  7. #生成测试文件
  8. open("3.txt","w+").write("""9.79.12.0
  9. 9.79.116.0
  10. 9.79.219.0
  11. 9.79.221.0
  12. 9.79.222.0
  13. 149.80.1.0
  14. 149.80.42.0
  15. 149.80.144.0
  16. 149.80.249.0
  17. 119.189.73.0
  18. 119.189.74.0
  19. 119.189.82.0
  20. 119.189.84.0
  21. 119.189.96.0
  22. 119.189.99.0
  23. 119.189.84.0
  24. 119.189.96.0
  25. 119.189.199.0
  26. 119.189.255.0""")
  27. txt=open("3.txt").readlines()
  28. abc=[r.split(".")[:-1] for r in txt]
  29. ab=sorted(list({r[0]+'.'+r[1] for r in abc}))
  30. for a in ab:
  31.     ccc=['.'.join(r.split(".")[:-1]) for r in txt if a+"." in r]
  32.     print('整理结果',min(ccc)+'.0'+'-'+max(ccc)+'.255')
  33. """
  34. 输出:
  35. 整理结果 119.189.199.0-119.189.99.255
  36. 整理结果 9.79.116.0-9.79.222.255
  37. 整理结果 149.80.1.0-149.80.42.255
  38. """
复制代码
去学去写去用才有进步。安装python3代码存为xx.py 双击运行或右键用IDLE打开按F5运行

TOP

本帖最后由 CrLf 于 2016-3-4 08:38 编辑

回复 14# neorobin


惭愧,玩笑话罢了,随便改
这大概是类似思路下的最优方案了吧?看到兄台代码,本想试试用异运算,大致原理类似这样:
  1. all=a^b
  2. flag=a 大于 b
  3. max=all^a*flag+b*!flag
复制代码
但无法简单判断两数大小,所以还是没法找到更好的方案

TOP

回复 7# CrLf

一样无异议.

JUST I THINK SO

对于max(a,b)和min(a,b), set /a 有这样一些实现:
min
a+(b-a)&(b-a>>31)
(a-b>>31)&a|(b-a>>31)&b
(a-b>>31)&a|~(a-b>>31)&b

max
a-(a-b)&(a-b>>31)
(a-b>>31)&b|(b-a>>31)&a
(a-b>>31)&b|~(a-b>>31)&a

大胆把大师级代码修改玩一下, 未定义的变量被看作 0 , 确实不能忘了, 呃, 我不想用除法!, 假设文档中并无负数. 以下
  1. @echo off & setlocal enabledelayedexpansion
  2. set /a "M=1<<31^-1"
  3. for /f "tokens=1-3 delims=. " %%a in (a.txt) do (
  4.     set /a "x=%%c,t=x-max[%%a.%%b],max[%%a.%%b]=x-(t&t>>31),p=min[%%a.%%b],p=p+(p-1>>31&M),t=p-x,min[%%a.%%b]=x+(t&t>>31)"
  5. )
  6. for /f "delims=max[]" %%a in ('set max[') do (
  7. echo %%a.!min[%%a]!.0-%%a.!max[%%a]!.255
  8. )
  9. pause
复制代码
1

评分人数

    • CrLf: 可能是该思路下的最优方案了吧PB + 10 技术 + 1

TOP

回复 12# Linuxer


    那些 %%a %%b 是 for 语句的变量,执行 set /a 时它们已经变成数字了...

TOP

哈哈。一看就知道必然是高大上的代码,,,留爪以备学习。看着满屏的%感觉很难。。。

TOP

回复 10# CrLf


    明白了,我还以为!是取反来着,呵呵。谢谢指教。

TOP

本帖最后由 CrLf 于 2014-8-25 23:26 编辑

回复 9# apang


玄机不在冒号,而在于变量延迟,可以参考此贴:http://bbs.bathome.net/viewthread.php?tid=15774

以此句为例:
  1. set /a "(!min[%%a.%%b]:min[%%a.%%b]=n!)/(n-min[%%a.%%b]>>31),min[%%a.%%b]=n"
复制代码
分解几个部分来解释一下:

1、(!min[%%a.%%b]:min[%%a.%%b]=n!)
因为变量 min[%%a.%%b] 的值一定为数字,所以脚本中的 !min[%%a.%%b]:min[%%a.%%b]=n! 会有如下变化:
当变量存在时,相当于 !min[%%a.%%b]!
当变量不存在时,相当于 min[%%a.%%b]=n,也就是把 n 赋值给 min[%%a.%%b]

2、(n-min[%%a.%%b]>>31)
>>运算符用于作位偏移计算,假如是 >>1 会将第 32 位的01状态复制到 31 位,丢弃第 1 位,其余位向右偏移
因为负数的第 32 位一定是 1,而正整数的 32 位为 0,所以得出一个规律:负数>>31 = -1,正数>>31 = 0
所以这句的作用是假如 n 小于 min[%%a.%%b] 则得到 1,否则得到 0

3、(!min[%%a.%%b]:min[%%a.%%b]=n!)/(n-min[%%a.%%b]>>31)
分子不重要,如上文说明仅用于在 min[%%a.%%b] 变量不存在时将其定义为 n,将其理解为任意数字皆可
而当分母为 0 时,计算出错,停止 set /a
所以如上文所述,这句相当于当 n 大等于 min[%%a.%%b] 时终止计算

4、min[%%a.%%b]=n
前一个算式执行成功后才会执行这句,将 min[%%a.%%b] 赋值为 n
1

评分人数

TOP

回复 7# CrLf


    (!min[%%a.%%b]:min[%%a.%%b]=n!) 猜测这个是条件判断,set /a中使用冒号以前没见过,请教CrLf,到哪里可以找到相关的用法和资料?

TOP

回复 7# CrLf


    无异议。

TOP

本帖最后由 CrLf 于 2014-8-25 00:52 编辑

如果我毫不谦虚地说这是大师级的写法,各位有异议吗...
  1. @echo off&setlocal enabledelayedexpansion
  2. (for /f "tokens=1-3 delims=. " %%a in (a.txt) do (
  3. set /a "(n=%%c)/(max[%%a.%%b]-n>>31),max[%%a.%%b]=n"
  4. set /a "(!min[%%a.%%b]:min[%%a.%%b]=n!)/(n-min[%%a.%%b]>>31),min[%%a.%%b]=n"
  5. )) 2>nul
  6. for /f "delims=max[]" %%a in ('set max[') do (
  7. echo %%a.!min[%%a]!.0-%%a.!max[%%a]!.255
  8. )
  9. pause
复制代码
支持乱序文本,但不对输出排序
1

评分人数

    • apang: 大师级,杠杠的技术 + 1

TOP

回复 3# uckiss


    真的可以用吗?
我发现有逻辑错误,以改正

TOP

本帖最后由 523066680 于 2014-8-24 17:23 编辑

也做一个咯
  1. @echo off
  2. setlocal enabledelayedexpansion
  3. set /a min=255, max=0
  4. for /f "tokens=1,2,3,4 delims=." %%a in (a.txt) do (
  5. if not "%%a.%%b" == "!ever!" (
  6. if defined ever (
  7. echo !ever!.!min!.0 - !ever!.!max!.0
  8. )
  9. set /a min=255, max=0
  10. )
  11. set ever=%%a.%%b
  12. if %%c gtr !max! (
  13. set /a max = %%c
  14. )
  15. if %%c leq !min! (
  16. set /a min = %%c
  17. )
  18. )
  19. echo !ever!.!min!.0 - !ever!.!max!.0
  20. pause
复制代码
未考虑前面两节地址打乱的情况,for 里面改成 ('sort /r a.txt') 可以解决一般情况。

TOP

>>  用两个这,就搞定,,,,谢了

TOP

回复 2# apang


    可以用, 谢谢   

就是处理过后,不会保存到文本,

得手动复制到文本才行
手动复制只能复制显示的部分,
帮忙加句代码,,自动保存到指定文本

TOP

返回列表