8

I need to edit a file like the following:

auto wlx00
allow-hotplug wlx00
iface wlx000 inet dhcp
iface wlx000 inet6 auto
  post-up sysctl -w net.ipv6.conf.wlx000.accept_ra=2
auto wlx000

the goal is to delete the lines starting with 'iface...inet6' and also delete the next few that start with space (can be none or more than one):

iface wlx000 inet6 auto
  post-up sysctl -w net.ipv6.conf.wlx000.accept_ra=2

and keep the rest intact for the following result:

auto wlx00
allow-hotplug wlx00
iface wlx000 inet dhcp
auto wlx000

I tried with sed using as follows:

sed -i.old -r -e "/iface\s*\w*\s*inet6.*/,\${d;/^\s.*/d;}" /etc/configfile

but it removes everything starting at the right place but erasing to the end. I just want to remove lines staring with space after the select iface text.

  • 1
    @fcm please let us know if the solutions below are ok. if not we can tweak it for you – user88036 Oct 17 '18 at 1:44
  • 1
    Possible duplicate of remove lines that contain a specific text in a file – user90704 Oct 17 '18 at 16:01
  • 1
    @TNT not the same question. This is NOT to delete a single line, is delete a line plus following lines staring with space. – fcm Oct 17 '18 at 16:30
  • 2
    Theoretically a duplicate, but not in practice -- I think it'd be good to provide a separate answer here that demonstrates how to match from a given pattern through subsequent lines that have leading whitespace. – Jeff Schaller Oct 17 '18 at 16:56
  • 1
    @rudic provided an excellent and elaborated answer that is far from being a simple search and delete, nothing on the suggested dup nears that. – fcm Oct 17 '18 at 17:04
7

Try this adaption of your sed one liner:

sed  '/iface\s*\w*\s*inet6.*/,/^[^ ]/ {/^[^ i]/!d}' file

It matches the range from your first pattern to the first line NOT starting with a space char, and deletes the lines starting with space or an "i" (for the leading iface). Need to rethink should the i be required after the block.

Looks like this works:

sed -n '/iface\s*\w*\s*inet6.*/ {:L; n; /^[ ]/bL;}; p' file

Pls try and report back.

6

A script for standard sed that uses an explicit loop to delete the lines:

/^iface .* inet6/ {
    :again
    N
    s/.*\n//
    /^[[:blank:]]/b again
}

The script finds the inet6 lines and then appends the next line to that line internally in the pattern space (with an embedded newline character in-between). It then deletes the pattern space up to and including the first newline character (this deletes the original inet6 line). It continues doing this until the pattern space does not start with a blank character (space or tab).

Testing:

$ cat file
auto wlx00
allow-hotplug wlx00
iface wlx000 inet dhcp
iface wlx000 inet6 auto
  post-up sysctl -w net.ipv6.conf.wlx000.accept_ra=2
auto wlx000
$ sed -f script.sed <file
auto wlx00
allow-hotplug wlx00
iface wlx000 inet dhcp
auto wlx000

Testing on artificial data:

$ cat file
something1
something2
iface have a inet6 here
   delete me
   me too
   same here
something3
something4
iface more something inet6
   be gone
   skip this
something5
$ sed -f script.sed <file
something1
something2
something3
something4
something5

The script as a "one-liner":

sed -e '/^iface .* inet6/ {' -e ':a' -e 'N;s/.*\n//;/^[[:blank:]]/ba' -e '}'
3

You've already got good answers for sed tool, but let me propose other, I believe much simpler, approach using pcregrep:

pcregrep -Mv '^iface.*inet6(.|\n )*' file

The regex should be self-explanatory - we search for pattern starting from the line ^iface.*inet6 and then group of any character OR new line followed by single space repeated zero or more times. Then we just need to instruct pcregrep to allow multi-linear matching with -M option and reverse the whole thing by -v (matched part will be removed).

  • I usually prefer to use pcregrep, far more intuitive. – Rui F Ribeiro Feb 21 at 20:31

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.