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

Wol*_*olf 7 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:~$ 
Run Code Online (Sandbox Code Playgroud)

然后,我将它通过管道传输到另一个 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:~$ 
Run Code Online (Sandbox Code Playgroud)

是否可以在不将 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:~$ 
Run Code Online (Sandbox Code Playgroud)

woo*_*god 12

实际上,您定义的字段分隔符-F是一个正则表达式。因此,应提供以下命令:

ip a | awk -F'[ /]+' '/inet / {print $3}'
Run Code Online (Sandbox Code Playgroud)


Kam*_*ski 11

ip a | awk '/inet / {FS="/"; $0=$2; print $1; FS=" "}'
Run Code Online (Sandbox Code Playgroud)

第一个匹配的记录根据默认FS(空格)拆分为字段。然后FS设置一个新的。当我们替换时$0=$2,分裂是根据新的FS。现在$1包含我们想要的东西,我们打印它。最后我们设置FS下一个匹配记录。


PEd*_*hur 10

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

ip -j -p -f inet a | awk -F \" '/local/ {print $4}'
Run Code Online (Sandbox Code Playgroud)

这会将ip address搜索作为 JSON 对象打印出来local,它恰好存储了 IP 地址。您可以使用更清晰jq

ip -j -p -f inet a | jq '.[].addr_info[].local'
Run Code Online (Sandbox Code Playgroud)

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

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

或者

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

在第一个命令中,我们使用index($2, "/")find where /is in$2然后使用substr生成子字符串。在秒钟就有一个,我们分手$2/,并将其存储在addr阵列。


Fre*_*ddy 7

您可以用/空字符串替换和以下字符:

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

  • @Wolf 以您觉得最好的方式为准,另请参阅:https://unix.stackexchange.com/help/someone-answers (2认同)