我有一个脚本,我需要在其中解析本地主机的 IP 地址,并将第二个八位字节替换为不同的值,但替换的值取决于当前的值......
例如,如果 IP 是10.10.100.6,那么我需要的结果是10.20.100.6,如果 IP 是10.20.100.6,那么我需要的结果是10.10.100.6
我尝试了以下方法:
nmcli con show eno16777984 | grep -E '^ipv4.address' | awk -F"/|[[:space:]]+" '{print $2}' | sed -e 's/^10\.10\./10.20./; s/^10\.20\./10\.10\./'
我遇到的问题是,sed
替换是按照命令中设置的顺序发生的。所以结果总是10.10....
有没有办法让 sed 仅在当前值与模式匹配时才替换值?
谢谢!
聚苯乙烯这需要是简短的一行代码,因为这行代码将通过在几个地方替换来执行,而执行此操作的人的经验/知识都有限,因此只需从文档中复制和粘贴即可。
更新
我最终找到了如何通过以下方式做到这一点awk
:
nmcli con show eno16777984 | grep -E '^ipv4.address' | awk -F"/|[[:space:]]+" '{print $2}' | awk -F. '{print $1"."($2 == "10" ? "20" : "10")"."$3"."$4}'
但下面有一些很好且简单的答案展示了如何做到这一点sed
。
答案1
只需添加t;
。
sed -e 's/^10\.10\./10.20./;t;s/^10\.20\./10\.10\./'
它会在成功时分支到最后。但你确实应该将所有这些 grep、awk、sed 合并到一个 awk 中。
答案2
要交换两个字符串,请使用临时的第三个字符串,该字符串不会以其他方式改回。
sed -e 's/^10\.10\./10.foo./g; s/^10\.20\./10.10./g; s/^10\.foo\./10.20./g'
答案3
无需在此处通过管道grep
或sed
进入awk
或awk
进入awk
。 awk
可以一次性完成这一切:
nmcli con show eno16777984 |
awk -F"/|[[:space:]]+" '
/^ipv4.address/ {
if ($2 ~ /^10\.10/) {
sub(/10\.10/,"10.20",$2);
} else if ($2 ~ /^10\.20/) {
sub(/10\.20/,"10.10",$2);
};
};
1'
在以 开头的行中ipv4.address
,如果第二个字段以 开头10.10
,则将其替换为10.20
;如果以 开头10.20
,则将其替换为10.10
。打印所有行,无论它们是否被修改。 (这1
是一个 awk 快捷方式 - 1 始终评估为 true,默认操作是打印...该行有效if true then print the current line
)。