标题: [文本处理] 如何获取相同IP段中C段(第三段)的最小值和最大值并按指定格式输出? [打印本页]
作者: uckiss 时间: 2014-8-24 11:01 标题: 如何获取相同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
先谢了
作者: apang 时间: 2014-8-24 12:24
本帖最后由 apang 于 2014-8-24 19:00 编辑
- @echo off & setlocal enabledelayedexpansion
- for /f "tokens=1-3 delims=." %%a in (a.txt) do (
- if defined Max%%a.%%b (
- if !Max%%a.%%b! lss %%c set "Max%%a.%%b=%%c"
- ) else set "Max%%a.%%b=%%c"
-
- if defined Min%%a.%%b (
- if !Min%%a.%%b! gtr %%c set "Min%%a.%%b=%%c"
- ) else set "Min%%a.%%b=%%c"
- )
-
- (for /f "tokens=1*delims==" %%a in ('"(set Min&set Max)|sort /+4"') do (
- if defined flag (
- if %%b gtr !b! (
- echo,!a:~3!.!b!.0-!a:~3!.%%b.0
- ) else echo,!a:~3!.%%b.0-!a:~3!.!b!.0
- set "flag="
- ) else set "a=%%a" & set /a b=%%b,flag=1
- ))>b.txt
- pause
复制代码
作者: uckiss 时间: 2014-8-24 15:30
回复 2# apang
可以用, 谢谢
就是处理过后,不会保存到文本,
得手动复制到文本才行
手动复制只能复制显示的部分,
帮忙加句代码,,自动保存到指定文本
作者: uckiss 时间: 2014-8-24 16:46
>> 用两个这,就搞定,,,,谢了
作者: 523066680 时间: 2014-8-24 17:01
本帖最后由 523066680 于 2014-8-24 17:23 编辑
也做一个咯- @echo off
- setlocal enabledelayedexpansion
- set /a min=255, max=0
- for /f "tokens=1,2,3,4 delims=." %%a in (a.txt) do (
- if not "%%a.%%b" == "!ever!" (
- if defined ever (
- echo !ever!.!min!.0 - !ever!.!max!.0
- )
- set /a min=255, max=0
- )
- set ever=%%a.%%b
- if %%c gtr !max! (
- set /a max = %%c
- )
- if %%c leq !min! (
- set /a min = %%c
- )
- )
- echo !ever!.!min!.0 - !ever!.!max!.0
- pause
复制代码
未考虑前面两节地址打乱的情况,for 里面改成 ('sort /r a.txt') 可以解决一般情况。
作者: apang 时间: 2014-8-24 19:05
回复 3# uckiss
真的可以用吗?
我发现有逻辑错误,以改正
作者: CrLf 时间: 2014-8-24 22:12
本帖最后由 CrLf 于 2014-8-25 00:52 编辑
如果我毫不谦虚地说这是大师级的写法,各位有异议吗...- @echo off&setlocal enabledelayedexpansion
- (for /f "tokens=1-3 delims=. " %%a in (a.txt) do (
- set /a "(n=%%c)/(max[%%a.%%b]-n>>31),max[%%a.%%b]=n"
- set /a "(!min[%%a.%%b]:min[%%a.%%b]=n!)/(n-min[%%a.%%b]>>31),min[%%a.%%b]=n"
- )) 2>nul
-
- for /f "delims=max[]" %%a in ('set max[') do (
- echo %%a.!min[%%a]!.0-%%a.!max[%%a]!.255
- )
- pause
复制代码
支持乱序文本,但不对输出排序
作者: 523066680 时间: 2014-8-24 22:58
回复 7# CrLf
无异议。
作者: apang 时间: 2014-8-25 19:40
回复 7# CrLf
(!min[%%a.%%b]:min[%%a.%%b]=n!) 猜测这个是条件判断,set /a中使用冒号以前没见过,请教CrLf,到哪里可以找到相关的用法和资料?
作者: CrLf 时间: 2014-8-25 20:13
本帖最后由 CrLf 于 2014-8-25 23:26 编辑
回复 9# apang
玄机不在冒号,而在于变量延迟,可以参考此贴:http://bbs.bathome.net/viewthread.php?tid=15774
以此句为例:- 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
作者: apang 时间: 2014-8-25 21:02
回复 10# CrLf
明白了,我还以为!是取反来着,呵呵。谢谢指教。
作者: Linuxer 时间: 2014-8-25 21:28
哈哈。一看就知道必然是高大上的代码,,,留爪以备学习。看着满屏的%感觉很难。。。
作者: CrLf 时间: 2014-8-26 00:29
回复 12# Linuxer
那些 %%a %%b 是 for 语句的变量,执行 set /a 时它们已经变成数字了...
作者: neorobin 时间: 2014-8-29 11:32
回复 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 , 确实不能忘了, 呃, 我不想用除法!, 假设文档中并无负数. 以下- @echo off & setlocal enabledelayedexpansion
- set /a "M=1<<31^-1"
- for /f "tokens=1-3 delims=. " %%a in (a.txt) do (
- 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)"
- )
-
- for /f "delims=max[]" %%a in ('set max[') do (
- echo %%a.!min[%%a]!.0-%%a.!max[%%a]!.255
- )
- pause
复制代码
作者: CrLf 时间: 2014-8-29 15:58
本帖最后由 CrLf 于 2016-3-4 08:38 编辑
回复 14# neorobin
惭愧,玩笑话罢了,随便改
这大概是类似思路下的最优方案了吧?看到兄台代码,本想试试用异运算,大致原理类似这样:- all=a^b
- flag=a 大于 b
- max=all^a*flag+b*!flag
复制代码
但无法简单判断两数大小,所以还是没法找到更好的方案
作者: codegay 时间: 2016-3-4 04:32
- """
- IP段整理成a.b.c.0-a.b.c.255的格式.py
- http://bbs.bathome.net/thread-31568-1-1.html
- 2016年3月3日 02:15:42 codegay
- """
- import pprint
- #生成测试文件
- open("3.txt","w+").write("""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""")
-
- txt=open("3.txt").readlines()
- abc=[r.split(".")[:-1] for r in txt]
- ab=sorted(list({r[0]+'.'+r[1] for r in abc}))
- for a in ab:
- ccc=['.'.join(r.split(".")[:-1]) for r in txt if a+"." in r]
- print('整理结果',min(ccc)+'.0'+'-'+max(ccc)+'.255')
-
- """
- 输出:
- 整理结果 119.189.199.0-119.189.99.255
- 整理结果 9.79.116.0-9.79.222.255
- 整理结果 149.80.1.0-149.80.42.255
- """
复制代码
欢迎光临 批处理之家 (http://bbs.bathome.net/) |
Powered by Discuz! 7.2 |