我的记录如下:
interface Vlan5
description customerA
ip address 1.1.1.1 255.255.255.0
ip address 2.2.2.1 255.255.255.0
ip address 3.3.3.1 255.255.255.0
no ip redirects
no ip unreachables
no ip proxy-arp
standby delay reload 90
standby 9 ip 1.1.1.1
standby 9 ip 2.2.2.1 secondary
standby 9 ip 3.3.3.1 secondary
standby 9 timers 2 6
standby 9 preempt delay minimum 60
我需要找到“ip address”的所有匹配项,并从这些行(IP地址)中获取第3和第4个字段。我已经得到了它,所以我正在查看正确的记录,但无法弄清楚如何在给定记录中的字段上返回多个匹配,其位置将如此变化。这是非工作代码片段,它让我返回“ip地址”,但我不知道如何获得后面的两个字段(或者如果这是最好的方法)。
if ... blah blah
custvlan=$(echo $i | awk 'BEGIN { FS="," } { print $4 }')
awk -v custvlan=$custvlan 'BEGIN { RS="!"; FS=" " }
{ if ( $1 ~ "interface" && $2 ~ "Vlan" )
{ seenvlan=gensub(/^Vlan/, "", "g", $2)
if ( seenvlan == custvlan )
match($0,/ip address/); print substr($0,RSTART,RLENGTH)
}
}
END {
}' device-config-file
我也尝试将RS重置为新行,希望它能以嵌套的方式工作,但它不会出现。以下修改的示例打印上面第一个示例中的字段3和4,而不是1.1.1.1 255.255.255.0
if ( seenvlan == custvlan )
RS="\n"; print "this is seenvlan " seenvlan
if ( $1 ~ ip && $2 ~ address )
print $3 " " $4
答案 0 :(得分:0)
您可以使用split()
为整个块添加换行符,并为每行split()
再次提取字段并检查前两个字段,例如:
awk -v custvlan=$custvlan 'BEGIN { RS="!"; FS=" " }
{ if ( $1 ~ "interface" && $2 ~ "Vlan" )
{ seenvlan=gensub(/^Vlan/, "", "g", $2)
if ( seenvlan == custvlan )
split($0, lines, "\n")
for (l in lines) {
line = lines[l]
split(line, fields, " ")
if (fields[1] == "ip" && fields[2] == "address") {
print fields[3], fields[4]
}
}
}
}
END {
}' device-config-file
它产生:
1.1.1.1 255.255.255.0
2.2.2.1 255.255.255.0
3.3.3.1 255.255.255.0
答案 1 :(得分:0)
您可以在不使用RS
的情况下执行此操作。例如,当bash中custvlan
设置为5
时:
awk -v custvlan=$custvlan '/^interface/ { show=$2=="Vlan" custvlan ? 1 : 0 }
show && /ip address/ { print $3,$4 }' device-config-file
1.1.1.1 255.255.255.0
2.2.2.1 255.255.255.0
3.3.3.1 255.255.255.0
创建虚拟"记录"设置show
变量与custvlan
变量匹配,仅在ip address
设置时打印出show
行的数据。
答案 2 :(得分:0)
另一个解决方案,使用RS="!"
来识别块(如上面给出的另一个答案,我假设是Cisco IOS配置格式),并FS="\n"
将每个块拆分成行。测试interface VlanX
(命令行中预期的custvlan
),然后依次循环遍历块中的每一行,并在空格上分割以ip address
开头的那些行。针对空字段调整的字段编号和数组索引。为了提高效率,它只假设一个这样的块,所以一旦发现它就会退出。
在Mac OS X 10.9上使用/usr/bin/awk
,gawk
和mawk
进行了测试。
BEGIN {
RS = "!"
FS = "\n"
}
$2 ~ "^ *interface Vlan" custvlan {
for (i=2; i<=NF; ++i) {
if ($i ~ /^ *ip address /) {
split($i, a, / */)
print a[4], a[5]
}
}
exit 0
}
示例输入:
!
! Last configuration change at 16:21:26 EEST Thu Sep 6 2012 by admin
! NVRAM config last updated at 16:21:46 EEST Thu Sep 6 2012 by admin
!
version 15.1
service timestamps debug datetime localtime
service timestamps log datetime localtime
no platform punt-keepalive disable-kernel-core
!
!
interface Vlan5
description customerA
ip address 1.1.1.1 255.255.255.0
ip address 2.2.2.1 255.255.255.0
ip address 3.3.3.1 255.255.255.0
no ip redirects
no ip unreachables
no ip proxy-arp
standby delay reload 90
standby 9 ip 1.1.1.1
standby 9 ip 2.2.2.1 secondary
standby 9 ip 3.3.3.1 secondary
standby 9 timers 2 6
standby 9 preempt delay minimum 60
!
interface Vlan6
description customerB
ip address 4.4.4.4 255.255.255.0
ip address 5.5.5.1 255.255.255.0
ip address 6.6.6.1 255.255.255.0
no ip redirects
no ip unreachables
no ip proxy-arp
standby delay reload 90
standby 9 ip 1.1.1.1
standby 9 ip 2.2.2.1 secondary
standby 9 ip 3.3.3.1 secondary
standby 9 timers 2 6
standby 9 preempt delay minimum 60
!
end
用法:
script.awk custvlan=5 sample.txt
=> 1.1.1.1 255.255.255.0
=> 2.2.2.1 255.255.255.0
=> 3.3.3.1 255.255.255.0
script.awk custvlan=6 sample.txt
=> 4.4.4.4 255.255.255.0
=> 5.5.5.1 255.255.255.0
=> 6.6.6.1 255.255.255.0
以下是一个更强大的解决方案(例如,安全地防止流浪!
个字符),需要mawk
或gawk
,它们支持RS
或 BEGIN {
RS = "\n( *!\n)+"
FS = "\n"
}
$1 ~ "^ *interface Vlan" custvlan {
for (i = 2; i <= NF; ++i) {
if ($i ~ /^ *ip address /) {
split($i, a, / */)
print a[4], a[5]
}
}
exit 0
}
中的正则表达式{1}}。用法是一样的:
{{1}}