如何替换与egrep匹配的较大字符串中的子字符串?

时间:2018-06-08 00:03:40

标签: regex bash awk sed grep

如何仅在下面的文本中单独替换/ 32到/ 128?

52.222.128.45/32
172.22.187.101/32
52.222.128.248/32
2600:2000:2046:2000:3:db06:4200:23a1/32
2600:2000:2046:5800:3:db06:4200:23a1/32
2600:2000:2046:7800:3:db06:4200:23a1/32

期望的输出:

52.222.128.45/32
172.22.187.101/32
52.222.128.248/32
2600:2000:2046:2000:3:db06:4200:23a1/128
2600:2000:2046:5800:3:db06:4200:23a1/128
2600:2000:2046:7800:3:db06:4200:23a1/128

egrep '\:[0-9a-f]{1,4}/32'匹配最后四个十六进制字符和/ 32但是如何保持相同的四个十六进制字符,它们只能将/ 32更改为/ 128?

谢谢!

3 个答案:

答案 0 :(得分:3)

$ cat /tmp/ips
52.222.128.45/32
172.22.187.101/32
52.222.128.248/32
2600:2000:2046:2000:3:db06:4200:23a1/32
2600:2000:2046:5800:3:db06:4200:23a1/32
2600:2000:2046:7800:3:db06:4200:23a1/32
$ cat /tmp/ips | sed 's%\(:[0-9a-f]\{1,4\}\)/32%\1/128%'
52.222.128.45/32
172.22.187.101/32
52.222.128.248/32
2600:2000:2046:2000:3:db06:4200:23a1/128
2600:2000:2046:5800:3:db06:4200:23a1/128
2600:2000:2046:7800:3:db06:4200:23a1/128

正则表达式的说明如下:https://regex101.com/r/FDjUct/1请注意,%用作分隔符而不是/,以避免必须转义/中的sed个字符。正则表达式。

根据您熟悉的$ cat /tmp/ips | sed '/:/s/32$/128/' 52.222.128.45/32 172.22.187.101/32 52.222.128.248/32 2600:2000:2046:2000:3:db06:4200:23a1/128 2600:2000:2046:5800:3:db06:4200:23a1/128 2600:2000:2046:7800:3:db06:4200:23a1/128 多少,可能会更清楚地使用:

32

以上命令使用sed addresses仅对包含128的行应用:和{{1}}的替换。

答案 1 :(得分:3)

关注awk可能会有所帮助。(根据Ed的评论在解决方案中将[0-9a-fA-F]更改为[[:xdigit:]]

awk -v value="128" 'match($0,/(([[:xdigit:]]){1,4}:){1,4}[0-9](:([[:xdigit:]]){1,4}){1,3}\//){$0=substr($0,RSTART,RLENGTH) value}1' Input_file

我在awk 4.1版本中对它进行了测试,以防您使用旧版本时使用awk --re-interval进行上述代码。

现在也添加非单线形式的解决方案。

awk -v value="128" '
match($0,/(([[:xdigit:]]){1,4}:){1,4}[0-9](:([[:xdigit:]]){1,4}){1,3}\//){
  $0=substr($0,RSTART,RLENGTH) value
}
1
'  Input_file

答案 2 :(得分:2)

您可以使用以下正则表达式:

^(([[:xdigit:]]{1,4}:){7}[[:xdigit:]]{1,4}\/)32$

demo

并将其嵌入sed命令:

sed -E 's@^(([0-9a-fA-F]{1,4}:){7}[0-9a-fA-F]{1,4}\/)32$@\1128@g' 

其中-E选项用于启用扩展正则表达式,如果您不指定此选项,则必须转义(,这很痛苦。

  • 您的IPv6地址中的大写字母也将被考虑在内!
  • ^$个锚点用于为正则表达式添加约束
  • @在您的查找/替换命令中用作分隔符,替换是对IPv6的反向引用,您添加128,因为32不在组中如果您已将其替换为128

<强> INPUT:

52.222.128.45/32
172.22.187.101/32
52.222.128.248/32
2600:2000:2046:2000:3:db06:4200:23a1/32
2600:2000:2046:5800:3:DB06:4200:23a1/32
2600:2000:2046:7800:3:dB06:4200:23a1/32

<强>输出:

52.222.128.45/32
172.22.187.101/32
52.222.128.248/32
2600:2000:2046:2000:3:db06:4200:23a1/128
2600:2000:2046:5800:3:DB06:4200:23a1/128
2600:2000:2046:7800:3:dB06:4200:23a1/128

使用awk您也可以获得类似的结果:

$ cat testip | awk -F'/' '/^([[:xdigit:]]{1,4}:){7}[[:xdigit:]]{1,4}\/32$/{print $1"/"128; next}1'
52.222.128.45/32
172.22.187.101/32
52.222.128.248/32
2600:2000:2046:2000:3:db06:4200:23a1/128
2600:2000:2046:5800:3:db06:4200:23a1/128
2600:2000:2046:7800:3:db06:4200:23a1/128

用作字段分隔符/和类似的正则表达式,当一行匹配您打印第一个字段(对应于IPv6部分)的模式后跟/128,然后跳转到下一行。默认情况下,您打印该行。