有很多文章解释了如何在shell中的grep匹配之后或之前显示n行。
我需要一个更复杂的解决方案:grep for a word,当匹配时,我需要在接下来的n行中进一步grep。理想情况下,因此我需要与第一个搜索匹配的所有行,并且DID与下一个n行中的grep不匹配。某种文本搜索递归。
这不是grep绑定,但可以使用任何Linux / Unix工具。
示例输出:
interface TenGigE0/3/0/0
description
service-policy output QOS
ipv4 mtu 1500
ipv4 address 13.24.15.3 255.255.255.252
carrier-delay up 3000 down 0
load-interval 30
dampening
!
interface TenGigE0/3/0/1
description Link To
!
interface TenGigE0/3/0/1.302
description
vrf 1671
ipv4 address 13.24.14.11 255.255.255.254
encapsulation dot1q 302
我只需要一个在配置中没有vrf行的接口列表。请注意,我从备份数据库获得此输出,而不是路由器本身。
我的一个笨拙的想法是合并“界面”和“界面”之间的所有文字!在一行中过滤掉包含单词“vrf”的行。我使用了awk'/ ^ interface /,/!/'但未能将输出合并为一行。
答案 0 :(得分:1)
我绝对肯定这可以更有效地完成,但我不是bash巫师。对this answer的充分赞誉。
您的意见。
interface TenGigE0/3/0/0
description
service-policy output QOS
ipv4 mtu 1500
ipv4 address 13.24.15.3 255.255.255.252
carrier-delay up 3000 down 0
load-interval 30
dampening
!
interface TenGigE0/3/0/1
description Link To
!
interface TenGigE0/3/0/1.302
description
vrf 1671
ipv4 address 13.24.14.11 255.255.255.254
encapsulation dot1q 302
!
由于您希望所有接口都没有vrf,我们希望
interface TenGigE0/3/0/0
interface TenGigE0/3/0/1
这将打印该输出。
first_search="^interface"
second_search="vrf"
file="interface.txt"
for line in $(grep -n "$first_search" $file | sed s'/:.*//'); do
if ! $( sed -n $line',/!/!d;p' $file \
| grep -q $second_search ); then
sed -n $line','$line'p' $file
fi
done
其中$first_search
是“紧跟''接口'后面的行的开头”,而$second_search
只是文本'vrf'。我将输出写入名为“interface.txt”的文件并将其分配给变量。
这是它的工作原理。执行这些部分中的每一部分以查看数据如何在它们之间传递。
grep -n "$first_search" $file
找到每个接口实例并打印找到它的行号。此输出通过管道输送到... sed s'/:.*//'
,删除grep中包括和后面的任何内容。我们只剩下匹配的行号。对于每一个,sed -n $line',/!/!d;p'
)。请参阅上面引用的答案,详细说明这一点。grep -q $second_search
),则不执行任何操作。否则,sed -n $line','$line'p' $file
打印找到原始匹配的行。注意:我添加了一个“!”到你的输入结束,因为我不想寻找“!”或EOF。