Eliminazione di una parte di un file di testo e delle seguenti righe usando sed


8

Devo modificare un file come il seguente:

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

l'obiettivo è quello di eliminare le righe che iniziano con 'iface ... inet6' e anche di eliminare quelle che iniziano con lo spazio (può essere nessuna o più di una):

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

e mantieni intatto il resto per il seguente risultato:

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

Ho provato con sed usando come segue:

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

ma rimuove tutto a partire dal posto giusto ma cancellando fino alla fine. Voglio solo rimuovere le linee che fissano con spazio dopo il testo iface selezionato.


1
@fcm per favore facci sapere se le soluzioni qui sotto sono ok. in caso contrario possiamo modificarlo per te

1
Possibile duplicato di righe

1
@TNT non è la stessa domanda. Questo NON è per eliminare una singola linea, è eliminare una linea più le seguenti linee che fissano con spazio.
fcm,

2
Teoricamente un duplicato, ma non in pratica - penso che sarebbe utile fornire qui una risposta separata che dimostri come abbinare da un determinato modello a linee successive che hanno spazi bianchi iniziali.
Jeff Schaller

1
@rudic ha fornito una risposta eccellente ed elaborata che è lungi dall'essere una semplice ricerca ed eliminazione, nulla sul dup suggerito si avvicina a questo.
fcm,

Risposte:


7

Prova questo adattamento del tuo sedone liner:

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

Corrisponde all'intervallo dal primo motivo alla prima riga NON iniziando con un carattere spazio e cancella le linee che iniziano con spazio o una "i" (per il primo iface). È necessario ripensare se inecessario dopo il blocco.

Sembra che funzioni:

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

Pls prova a riferire.


6

Uno script per standard sedche utilizza un ciclo esplicito per eliminare le righe:

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

Lo script trova le inet6righe e quindi aggiunge la riga successiva a quella riga internamente nello spazio del pattern (con un carattere di nuova riga incorporato tra di loro). Elimina quindi lo spazio del motivo fino al primo carattere della riga incluso e incluso (questo elimina la inet6riga originale ). Continua così fino a quando lo spazio del motivo non inizia con un carattere vuoto (spazio o scheda).

test:

$ 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

Test su dati artificiali:

$ 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

La sceneggiatura come "one-liner":

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

3

Hai già buone risposte per lo sedstrumento, ma lasciami proporre un altro approccio, credo molto più semplice, usando pcregrep:

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

La regex dovrebbe essere autoesplicativa: cerchiamo il pattern partendo dalla linea ^iface.*inet6e quindi dal gruppo di qualsiasi carattere O dalla nuova linea seguita da uno spazio singolo ripetuto zero o più volte. Quindi dobbiamo solo istruire pcregrepper consentire la corrispondenza multi-lineare con l' -Mopzione e invertire il tutto di -v(la parte abbinata verrà rimossa).


Di solito preferisco usare pcregrep, molto più intuitivo.
Rui F Ribeiro,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.