Suppression d'une partie d'un fichier texte et des lignes suivantes à l'aide de sed

8

J'ai besoin de modifier un fichier comme celui-ci:

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'objectif est de supprimer les lignes commençant par «iface ... inet6» et également de supprimer les suivantes commençant par l'espace (peut être aucune ou plusieurs):

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

et garder le reste intact pour le résultat suivant:

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

J'ai essayé avec sed en utilisant comme suit:

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

mais il supprime tout en commençant au bon endroit mais en effaçant jusqu'à la fin. Je veux juste supprimer les lignes qui regardent l'espace après le texte iface sélectionné.

fcm
la source
1
@fcm veuillez nous faire savoir si les solutions ci-dessous sont correctes. sinon, nous pouvons le modifier pour vous
1
Duplication possible de lignes
1
@TNT n'est pas la même question. Ce n'est PAS pour supprimer une seule ligne, c'est supprimer une ligne plus les lignes suivantes en commençant par un espace.
fcm
2
Théoriquement un doublon, mais pas dans la pratique - je pense qu'il serait bon de fournir ici une réponse distincte qui montre comment faire la correspondance à partir d'un modèle donné à travers les lignes suivantes qui ont des espaces blancs en tête.
Jeff Schaller
1
@rudic a fourni une excellente réponse élaborée qui est loin d'être une simple recherche et suppression, rien sur le dup suggéré ne s'en rapproche.
fcm

Réponses:

7

Essayez cette adaptation de votre sedone liner:

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

Il correspond à la plage de votre premier modèle à la première ligne ne commençant pas par un caractère d'espace et supprime les lignes commençant par un espace ou un "i" (pour l'interlignage iface). Besoin de repenser si inécessaire après le blocage.

On dirait que cela fonctionne:

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

Veuillez essayer de faire rapport.

RudiC
la source
6

Un script pour standard sedqui utilise une boucle explicite pour supprimer les lignes:

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

Le script trouve les inet6lignes, puis ajoute la ligne suivante à cette ligne en interne dans l'espace de motif (avec un caractère de nouvelle ligne incorporé entre les deux). Il supprime ensuite l'espace de motif jusqu'au premier caractère de nouvelle ligne inclus (cela supprime la inet6ligne d' origine ). Il continue ainsi jusqu'à ce que l'espace de motif ne commence pas par un caractère vide (espace ou tabulation).

Essai:

$ 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 sur données artificielles:

$ 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

Le script en "one-liner":

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

Vous avez déjà de bonnes réponses pour l' sedoutil, mais permettez-moi d'en proposer une autre, je pense beaucoup plus simple, en utilisant pcregrep:

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

L'expression régulière doit être explicite - nous recherchons un motif à partir de la ligne ^iface.*inet6puis un groupe de n'importe quel caractère OU une nouvelle ligne suivie d'un espace unique répété zéro ou plusieurs fois. Ensuite, nous avons juste besoin d'instruire pcregreppour autoriser la correspondance multi-linéaire avec -Moption et inverser le tout par -v(la partie correspondante sera supprimée).

jimmij
la source
Je préfère généralement utiliser pcregrep, beaucoup plus intuitif.
Rui F Ribeiro