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]

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'
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.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.