![我可以拆分为两个字符,只运行 awk 一次吗?](https://linux22.com/image/173782/%E6%88%91%E5%8F%AF%E4%BB%A5%E6%8B%86%E5%88%86%E4%B8%BA%E4%B8%A4%E4%B8%AA%E5%AD%97%E7%AC%A6%EF%BC%8C%E5%8F%AA%E8%BF%90%E8%A1%8C%20awk%20%E4%B8%80%E6%AC%A1%E5%90%97%EF%BC%9F.png)
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 }'