从半结构化输入中匹配“关键字值”对

从半结构化输入中匹配“关键字值”对

有时,我从包含“键值”对的命令中获得输出,每行可能不止一对。作为一个可重复的示例,请考虑以下命令ip addr show dev eth0

ip addr show dev eth0 | grep -v link/ether
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
    inet 10.0.2.15/24 brd 10.0.2.255 scope global eth0
       valid_lft forever preferred_lft forever
    inet6 fe80::a00:27ff:fe0f:dbb3/64 scope link
       valid_lft forever preferred_lft forever

出于本示例的目的,我可能希望捕获 、 和 后面的值mtuinetbrd1500此处分别为 、10.0.2.15/2410.0.2.255)。可以假设每个关键字在输入中不会出现多次。

我认为处理此问题的唯一方法是将源命令的输出捕获到临时变量,并重复解析该变量,直到处理完所有关键字为止。

是否有更简单或更好的方法来挑选这些“键值”对,丢弃文本的其余部分?

建议的示例提供和无序输出:

ip addr show dev eth0 | someCommand brd inet mtu
mtu 1500
inet 10.0.2.15/24
brd 10.0.2.255

答案1

假设键名称最多出现一次,您可以尝试以下方法。

ip addr show dev eth0 | perl -ne 'chomp; foreach $param (qw(mtu inet brd)) { /($param)\s+(\S+)/ && do { print "$1 $2\n"; }}'

答案2

这是一个 awk 解决方案,它将每个单词放在自己的行上,每当它找到指定的键之一时,就会打印它和下一个单词。键实际上是一个需要匹配整个单词的正则表达式。

ip addr show dev eth1 |
tr -s ' ' '\n' |
awk -v keys='mtu|inet|brd' '
    match($0, "^(" keys ")$") {printf "%s ", $0; getline; print}
'

相关内容