2

What I have:

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]

What I want from that:

Get all data between pattern 1 (For example 2/1/6.2061) and the ends of the block (that shoudl be ! character)

Now i tried many ways with sed and awk as shown in many similar threads:

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$

And

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$

And much more variants like sed with !d and much more. If I use

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

it will shown any matches (so thousands and thousands of lines)

I post here just some threads i followed:


I found the problem by making a new file putting the example text into.

if i use:

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$

it works [because it is the "first block of the text"] but if i try to get the second block by hitting:

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

it doesn't work [because I'am searching interface 6.2062 instead of 6.2061]

muru
  • 72,889

2 Answers2

0

Your first sed example doesn't work for the second and following blocks, because /!/q (the backslash may lead to undefined behaviour, so I drop it) is already executed for the first ! and the script stops there (same for the exit of the awk script). So execute it only after the block, use

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

But a simple

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

like in your second attempt will also work, if you have no problem with wasting some cpu cycles.

And for future scripts, I suggest to use a different delimiter of the address pattern if it contains slashes like

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

Easier to read, right?

And yes, you can also use !d:

sed '\_2/1/6.2062_,/!/!d'
Philippos
  • 13,453
0

In your final awk scipt change:

p ; /!/{exit}

to

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

so you exit after processing the block you're interested in rather than exiting at the end of the first block in the file.

Ed Morton
  • 31,617