用特定数字替换数字范围 [英] Replace range of numbers with certain number
问题描述
我需要用某个数字替换一系列数字.我真的很努力地用 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屋!