Excluindo parte de um arquivo de texto e seguindo as linhas usando sed

8

Eu preciso editar um arquivo como o seguinte:

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

o objetivo é excluir as linhas que começam com 'iface ... inet6' e também excluir as próximas que começam com espaço (podem ser nenhuma ou mais que uma):

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

e mantenha o restante intacto para o seguinte resultado:

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

Eu tentei usar sed usando o seguinte:

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

mas remove tudo começando no lugar certo, mas apagando até o fim. Eu só quero remover linhas olhando com espaço após o texto select iface.

    
por fcm 17.10.2018 / 03:28

3 respostas

7

Experimente esta adaptação do seu sed one liner:

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

Ele corresponde ao intervalo do primeiro padrão até a primeira linha que NÃO inicia com um caractere de espaço e exclui as linhas que começam com espaço ou um "i" (para o primeiro iface ). Precisa repensar se i for necessário após o bloqueio.

Parece que isso funciona:

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

Pls tente denunciar.

    
por 17.10.2018 / 12:26
6

Um script para o padrão sed que usa um loop explícito para excluir as linhas:

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

O script localiza as linhas inet6 e, em seguida, anexa a linha seguinte a essa linha internamente no espaço padrão (com um caractere de nova linha incorporado entre elas). Em seguida, exclui o espaço de padrão até e incluindo o primeiro caractere de nova linha (isso exclui a linha inet6 original). Ele continua fazendo isso até que o espaço padrão não comece com um caractere em branco (espaço ou tabulação).

Teste:

$ 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

Teste em dados artificiais:

$ 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

O script como "one-liner":

sed -e '/^iface .* inet6/ {' -e ':a' -e 'N;s/.*\n//;/^[[:blank:]]/ba' -e '}'
    
por 19.10.2018 / 11:05
2

Você já tem boas respostas para a ferramenta sed , mas deixe-me propor outra abordagem, acredito muito mais simples, usando pcregrep :

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

O regex deve ser auto-explicativo - nós procuramos por um padrão começando pela linha ^iface.*inet6 e então o grupo de qualquer caractere OU nova linha seguido por espaço único repetido zero ou mais vezes. Então nós só precisamos instruir pcregrep para permitir a correspondência multi-linear com a opção -M e reverter a coisa toda por -v (a parte correspondente será removida).

    
por 28.10.2018 / 03:41