如何从两个模式(包括它们)之间选择第一次出现

如何从两个模式(包括它们)之间选择第一次出现

我拥有的:

interface GigabitEthernet0/2/1/6.2061
 description --> Some description here
 service-policy input BESTEFFORT-IN
 service-policy output Egress_30M
 vrf VPN-s2s
 ipv4 mtu 1500
 ipv4 address 222.222.222.1 255.255.255.252
 ipv4 unreachables disable
 dot1q vlan 2061
!
interface GigabitEthernet0/2/1/6.2062
 description Some Description here too
 service-policy input BESTEFFORT-IN
 vrf TRUSTED-3879
 ipv4 mtu 1500
 ipv4 address 111.111.111.111 255.255.255.252
--
[thousands of same data blocks]

我想从中得到什么:

获取模式 1(例如 2/1/6.2061)和块末尾(应该是 ! 字符)之间的所有数据

现在我尝试了使用 sed 和 awk 的多种方法,如许多类似的线程所示:

usr@mpls-fa-1:~/CIRCUITI_DA_DISMETTERE$ awk '/2\/1\/6.2061/{p=1} p; /\!/{exit}' idc3-sfc
usr@mpls-fa-1:~/CIRCUITI_DA_DISMETTERE$

usr@mpls-fa-1:~/CIRCUITI_DA_DISMETTERE$ sed -n -e '/2\/1\/6.2061/,/\!/p ; /\!/q' idc3-sfc
usr@mpls-fa-1:~/CIRCUITI_DA_DISMETTERE$

还有更多变体,例如 sed 和 !d 等等。如果我使用

sed -n -e '/2\/1\/6.2061/,/\!/p ;' idc3-sfc
awk '/2\/1\/6.2061/{p=1} p' idc3-sfc

它将显示任何匹配项(所以成千上万行)

我在这里发布的只是我关注的一些主题:


我通过创建一个新文件将示例文本放入其中发现了问题。

如果我使用:

usr@mpls-fa-1:~/CIRCUITI_DA_DISMETTERE$ awk '/2\/1\/6.2061/{p=1} p ; /!/{exit}' TEST
interface GigabitEthernet0/2/1/6.2061
 description --> Some description here
 service-policy input BESTEFFORT-IN
 service-policy output Egress_30M
 vrf VPN-s2s
 ipv4 mtu 1500
 ipv4 address 222.222.222.1 255.255.255.252
 ipv4 unreachables disable
 dot1q vlan 2061
!
usr@mpls-fa-1:~/CIRCUITI_DA_DISMETTERE$

它有效[因为它是“文本的第一个块”]但是如果我尝试通过点击来获取第二个块:

usr@mpls-fa-1:~/CIRCUITI_DA_DISMETTERE$ awk '/2\/1\/6.2062/{p=1} p ; /!/{exit}' TEST
usr@mpls-fa-1:~/CIRCUITI_DA_DISMETTERE$

它不起作用[因为我正在搜索接口 6.2062 而不是 6.2061]

答案1

您的第一个sed示例不适用于第二个和后续块,因为/!/q(反斜杠可能会导致未定义的行为,所以我将其删除)已经在第一个块中执行,!并且脚本在那里停止(与脚本exit的相同awk)。因此仅在块之后执行它,使用

sed -n '/2\/1\/6.2062/,/!/{p;/!/q;}'

但一个简单的

sed -n '/2\/1\/6.2062/,/!/p'

如果你不介意浪费一些CPU周期,就像你的第二次尝试一样。

对于未来的脚本,如果地址模式包含斜杠,我建议使用不同的分隔符,例如

sed -n '\_2/1/6.2062_,/!/p'

更容易阅读,对吗?

是的,您还可以使用!d

sed '\_2/1/6.2062_,/!/!d'

答案2

在最后的 awk 脚本更改中:

p ; /!/{exit}

p {print; if (/!/) exit}

因此,您在处理您感兴趣的块后退出,而不是在文件中第一个块的末尾退出。

相关内容