我可以拆分为两个字符,只运行 awk 一次吗?

我可以拆分为两个字符,只运行 awk 一次吗?

ip a生成一堆 IP 地址和接口状态

通过awk '/inet / {print $2}',我设法获取 IP 和子网

wolf@linux:~$ ip a | awk '/inet / {print $2}'
127.0.0.1/8
10.10.0.1/24
10.10.1.1/24
wolf@linux:~$ 

然后,我将其通过管道传输到另一个 awk 以删除 CIDR 符号。

wolf@linux:~$ ip a | awk '/inet / {print $2}' | awk -F / '{print $1}'
127.0.0.1
10.10.0.1
10.10.1.1
wolf@linux:~$ 

是否可以在不将 awk 输出通过管道传输到另一个 awk 的情况下执行此操作?

所需输出

wolf@linux:~$ ip a | <awk syntax here without additional piping>
127.0.0.1
10.10.0.1
10.10.1.1
wolf@linux:~$ 

答案1

实际上,您定义使用的字段分隔符-F是正则表达式。因此以下命令应该传递:

ip a | awk -F'[ /]+' '/inet / {print $3}'

答案2

ip a | awk '/inet / {FS="/"; $0=$2; print $1; FS=" "}'

第一个匹配记录根据默认值FS(空格)拆分为字段。然后FS设置一个新的。当我们替换时$0=$2,会根据新的再次进行分裂FS。现在$1包含了我们想要的内容,我们将其打印出来。最后我们设置FS下一个匹配记录。

答案3

对于这个非常具体的情况,您是否考虑过更好地使用ip?例如:

ip -j -p -f inet a | awk -F \" '/local/ {print $4}'

这会将密钥ip address搜索打印为 JSON 对象local,该密钥恰好存储了 IP 地址。是更锐利,你可以使用jq

ip -j -p -f inet a | jq '.[].addr_info[].local'

我推荐最后一个命令,因为它不会受到ip addr输出变化的影响。但是,如果您真的喜欢最初的设计,我会选择:

ip a | awk '/inet / {print substr($2, 1, index($2,"/")-1)}'

或者

ip a | awk '/inet / {split($2, addr, "/"); print addr[1]}'

在第一个命令中,我们使用index($2, "/")查找其中的位置/$2然后使用它substr来生成子字符串。在几秒钟内,我们将其拆分$2并将/其存储在addr数组中。

答案4

您可以将/以下字符替换为空字符串:

ip a | awk '/inet /{ sub(/\/.*/, "", $2); print $2 }'

相关内容