用 Bash 替换文件中不同格式的 IP 地址?

Replacing differently formatted IP addresses within a file with Bash?

上下文: 我有几个 .properties 文件,其中包含以下形式的 IP 地址:

    advertised.listeners=PLAINTEXT://ip-68-51-0-82.ec2.internal:9092
    advertised.host.name=ip-68-51-0-82.ec2.internal

(IP 地址已随机化以匿名)

理论上的解决方案: 我试图用 bash 命令的结果自动替换 .properties 文件中提到的 IP 地址 hostname -i 来自 bash 脚本(与在 VIM 中手动编辑 IP 相对)。

问题: hostname -i returns 我需要的IP地址,但格式不同。它 returns 62.57.0.85 是点符号而不是破折号。

目标: 将文件的文本更改为现在阅读:

advertised.listeners=PLAINTEXT://ip-62-57-0-85.ec2.internal:9092
advertised.host.name=ip-62-57-0-85.ec2.internal

我该怎么做?我会使用类似 sed 的东西吗?

更新(2021 年 7 月 6 日在 19:06): 在查看答案并确定对问题的进一步限制后,这里是适用于我:

sed -i "s|68-51-0-82|$(hostname -i | tr . -)|g" server.properties

为了进一步详细说明,我能够对要替换的 IP 进行硬编码,因为我知道它永远是相同的。如果您不这样做,并且需要针对任何潜在 IP 地址进行模式匹配,请参阅此问题的原始答案。

至于tr的用法,它是将主机名格式(默认为点表示法)转换为破折号的一种快速简便的方法。然后,我通过 $ 变量

直接在 sed 命令中使用 tr 命令的输出

UPDATED 基于 OP 的进一步 comments/clarifications:

$ oldip='68-51-0-82'                        # OP knows in advance the IP that needs to be replaced in the file
$ newip='62-57-0-85'                        # OP has already swapped out periods for hyphens
$ sed "s/${oldip}/${newip}/g" .properties
advertised.listeners=PLAINTEXT://ip-62-57-0-85.ec2.internal:9092
advertised.host.name=ip-62-57-0-85.ec2.internal

如果 OP 知道 oldip 总是 相同(即 68-51-0-82),则可以将其硬编码到 sed 调用中像这样:

$ sed "s/68-51-0-82/${newip}/g" .properties
advertised.listeners=PLAINTEXT://ip-62-57-0-85.ec2.internal:9092
advertised.host.name=ip-62-57-0-85.ec2.internal


假设:

  • 在我的虚拟机上 hostname -i ==> fe80::5454:7ccf:aa17:f765%13 10.8.1.6 192.168.1.4 ...所以我假设 OP 已经将新的 IP 地址解析为一个变量(例如,newip
  • 文件中的所有 ip 地址都符合 OP 发布的格式,即 <stuff>.ip-n1-n2-n3-n4.<stuff>)

使用 sed 的一个想法:

$ cat .properties
advertised.listeners=PLAINTEXT://ip-68-51-0-82.ec2.internal:9092
advertised.host.name=ip-68-51-0-82.ec2.internal

$ newip='62.57.0.85'

$ sed "s/ip-[^\.]+\./ip-${newip//./-}\./" .properties
advertised.listeners=PLAINTEXT://ip-62-57-0-85.ec2.internal:9092
advertised.host.name=ip-62-57-0-85.ec2.internal

其中:

  • ip-[^\.]+\. - 匹配字符串 ip- + <everything that's not a period> + 文字句点 (.)
  • ip-${newip//./-}\. - 替换为字符串 ip- + 我们的变量(句点用连字符替换)+ 文字句点 (.)

如果 OP 正在寻找覆盖 .properties,并且已验证此 sed 命令执行预期的操作,则可以添加 -i 标志以告诉 sed 覆盖输入文件(即 .properties)。