Brian Tillman
Brian Tillman

Reputation: 21

SED delete lines between two pattern matches

I am trying to replace lines between two pattern/string matches using SED see below. I need to delete lines below interface GigabitEthernet0/3 up to interface GigabitEthernet0/4, but leaving both interface names.

interface GigabitEthernet0/2
 duplex full
 mls qos trust dscp
 spanning-tree portfast
!
interface GigabitEthernet0/3
 mls qos trust dscp
 spanning-tree portfast
!
interface GigabitEthernet0/4
 mls qos trust dscp
!

outcome:

interface GigabitEthernet0/2
 duplex full
 mls qos trust dscp
 spanning-tree portfast
!
interface GigabitEthernet0/3
!
interface GigabitEthernet0/4
 mls qos trust dscp
!

Upvotes: 2

Views: 2977

Answers (5)

Lri
Lri

Reputation: 27633

$ cat test
1
start
2
end
3
$ sed -n '1,/start/p;/end/,$p' test
1
start
end
3
$ sed '/start/,/end/d' test
1
3

Upvotes: 1

Jonathan Leffler
Jonathan Leffler

Reputation: 755010

The basic answer seems simple to me:

sed -e "/interface GigabitEthernet0\/3/p" \
    -e "/interface GigabitEthernet0\/4/p" \
    -e "/interface GigabitEthernet0\/3/,/interface GigabitEthernet0\/4/d" "$@"

Print lines matching 'interface GigabitEthernet0/3', and lines containing 'interface GigabitEthernet0/4'; delete the lines between and including the two.

The only possible issue is that if there is 'interface GigabitEthernet0/4' and no preceding 'interface GigabitEthernet0/3', then that line will be doubled up. If that's an actual problem, then go for a more complex script:

sed -e "/interface GigabitEthernet0\/3/,/interface GigabitEthernet0\/4/{
        /interface GigabitEthernet0\/3/p
        /interface GigabitEthernet0\/4/p
        d
        }" "$@"

If you're adamant it must be one line, use semicolons, but the result is illegible.

Upvotes: 0

Brian Tillman
Brian Tillman

Reputation: 21

after posting I found my answer: here's my solution

cat somerouter.config | sed '/interface GigabitEthernet0\/3/,/interface GigabitEthernet0\/4/{/^interface GigabitEthernet0\/4/p;d;}' somerouter.config > somenewerrouter.config 

Then I just add back interface 0/3 with

sed -e '/interface\ GigabitEthernet0\/4/ i\
interface\ GigabitEthernet0\/3\
 description\ NOT USED\
 shutdown\
!' $filesw.tmp.1 > $filesw.tmp.2

Upvotes: 0

potong
potong

Reputation: 58558

This might work for you:

sed -e '\#^interface GigabitEthernet0/3#,/^!/{//!d}' input_file

or as you described it in the question:

sed -e '\#^interface GigabitEthernet0/3#,\#^interface GigabitEthernet0/4#{//!d;/4/s/^/!\n/}' input_file

presuming you want to preserve the ! on the line prior to the second interface. If you don't want the ! then omit /4/s/^/!\n/ from the last bit of the sed command

Upvotes: 0

Income:

$> cat ./text 
interface GigabitEthernet0/2
 duplex full
 mls qos trust dscp
 spanning-tree portfast
!
interface GigabitEthernet0/3
 mls qos trust dscp
 spanning-tree portfast
!
interface GigabitEthernet0/4
 mls qos trust dscp
!

Outcome:

$> cat ./text | sed '/interface GigabitEthernet0\/3/,/\!/c interface GigabitEthernet0\/3\n!'
interface GigabitEthernet0/2
 duplex full
 mls qos trust dscp
 spanning-tree portfast
!
interface GigabitEthernet0/3
!
interface GigabitEthernet0/4
 mls qos trust dscp
!

Sed can work with multi-line patterns. We just use c command which is changing matched pattern (from interface GigabitEthernet0/3 to !) with interface GigabitEthernet0/3 and !.

Upvotes: 1

Related Questions