用特定数字替换数字范围 [英] Replace range of numbers with certain number

查看:27
本文介绍了用特定数字替换数字范围的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我需要用某个数字替换一系列数字.我真的很努力地用 sed(如 sed "s/[33-64]/64/")或 awk 自己编写代码,但总是得到错误的结果.它倾向于替换个位数而不是数字......我需要的是:替换 0-32 -> 32, 33-64 -> 64, 65-128 -> 128, 129-255 -> 255.在这些之间数字是 IP,应该保持不变.我认为这个命令是选择所有,但 IPs:

I need to replace a range of numbers with a certain number. I really tried it hard to code it myself with sed (like sed "s/[33-64]/64/") or awk, but always get wrong results. It tends to replace single digits instead of numbers... What I need would be: Replacing 0-32 -> 32, 33-64 -> 64, 65-128 -> 128, 129-255 -> 255. In between these numbers are IPs, which should stay untouched. I think this command is selecting all, but IPs:

sed '/[0-9]{1,3}.[0-9]{1,3}.[0-9]{1,3}.[0-9]{1,3}/! ...  '

所以我有一个这样的文件:

So I have a file like this:

65.74.16.161
232
10.128.8.72
63
10.128.14.13
100
10.128.8.58
32
10.128.4.129
60
10.128.240.18
59

它应该是这样的:

65.74.16.161
255
10.128.8.72
64
10.128.14.13
128
10.128.8.58
32
10.128.4.129
64
10.128.240.18
64

推荐答案

[33-64] 定义了一个字符类,是一种有趣的写法[3-6] 并且确实只匹配单个字符——3、4、5 或 6 中的任何单个数字.如果你真的想用 sed 来做,并且你关心 33 中的值到 64,那么你必须以不同的方式写出来——而且要详细得多.

The [33-64] defines a character class and is a funny way of writing [3-6] and does indeed only match a single character — any single digit from 3, 4, 5 or 6. If you really want to do it with sed, and you're concerned with values from 33 to 64, then you have to write it out differently — and much more verbosely.

部分取决于您拥有哪个版本的 sed.一个适用于经典 sed 的解决方案是:

In part it depends on which version of sed you have. A solution that will work with classic sed is:

sed -e 's/^[0-9]$/32/' 
    -e 's/^[12][0-9]$/32/' 
    -e 's/^3[012]$/32/' 
    -e 's/^3[3-9]$/64/' 
    -e 's/^[45][0-9]$/64/' 
    -e 's/^6[0-4]$/64/' 
    -e 's/^6[5-9]$/128/' 
    -e 's/^[7-9][0-9]$/128/' 
    -e 's/^1[01][0-9]$/128/' 
    -e 's/^12[0-8]$/128/' 
    -e 's/^129$/255/' 
    -e 's/^1[3-9][0-9]$/255/' 
    -e 's/^2[0-4][0-9]$/255/' 
    -e 's/^25[0-5]$/255/'

但是,正如你所看到的,这很痛苦.如果你有 GNU sed,你可以使用 -r 选项来启用扩展的正则表达式;如果你有 Mac OS X 或 BSD sed,你可以使用 -E 选项来启用扩展的正则表达式.那么你可以将上面的代码缩减为:

But, as you can see, it is quite painful. If you have GNU sed, you can use the -r option to enable extended regular expressions; if you have Mac OS X or BSD sed, you can use the -E option to enable extended regular expressions. Then you can reduce the code above to:

sed -E 
    -e 's/^([0-9]|[12][0-9]|3[012])$/32/' 
    -e 's/^(3[3-9]|[45][0-9]|6[0-4])$/64/' 
    -e 's/^(6[5-9]|[7-9][0-9]|1[01][0-9]|12[0-8])$/128/' 
    -e 's/^(129|1[3-9][0-9]|2[0-4][0-9]|25[0-5])$/255/'

但是,使用 awk 可能会更好:

However, you might do better using awk:

awk '/^[0-9][0-9]*$/ { if      ($1 <=  32) print  32
                       else if ($1 <=  64) print  64
                       else if ($1 <= 128) print 128
                       else if ($1 <= 255) print 255
                       else                print  $1
                       next
                     }
     { print }'

最后的 else 子句准确地打印出任何意外的值,例如 256 或 999,或者实际上是 123456789.有些人会用 1 代替 { print }awk 脚本中匹配和打印 IP 地址的部分.

The final else clause accurately prints any unexpected values, such as 256 or 999 or, indeed, 123456789. There are those who would write 1 in place of { print } — the part of the awk script that matches and prints the IP addresses.

这篇关于用特定数字替换数字范围的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆