lignes d’impression entre deux occurrences d’un REGEX

Suppose que j’ai un fichier texte comme suit

candy_box a orange blue red sweet_box a Jelly1 jelly2 poison_box c 12a b154 Kl213 chox_box a Snickers; MARS poison_box c k121238 asf12 as3124 

Mon script devrait sortir comme ceci (évitez la box C et son contenu)

 candy_box a orange blue red sweet_box a Jelly1 jelly2 chox_box a Snickers; MARS 

J’ai essayé de grep "box c" et d’éviter les lignes qui le suivent en utilisant Sed. Mais le problème est que j’ai des contenus variables dans la boîte c. c’est-à-dire que certains contenus de la boîte c ont 3 lignes, certains ont 4 lignes.

Alors, comment peut-on grep des choses entre deux occurrences d’un même REGEX et effectuer des opérations de texte dans les lignes contenant entre elles?

awk peut être utile pour cela:

 $ awk 'NF==2 {if (/box c$/) {f=0} else {f=1}} f' file candy_box a orange blue red sweet_box a Jelly1 jelly2 chox_box a Snickers; MARS 

Explication

  • NF==2 {if (/box c$/) {f=0} else {f=1}} s’il y a deux champs, faites:
    • if (/box c$/) {f=0} si la chaîne se termine par la box c , éteignez ensuite le drapeau.
    • sinon, allumez le drapeau.
  • f quand c’est vrai, il exécute le comportement de awk par défaut -> {print $0} .
 awk '/_box .$/{p=1}/_box c$/{p=0}p' file candy_box a orange blue red sweet_box a Jelly1 jelly2 chox_box a Snickers; MARS 

Voici un awk

 awk '/box c/{f=1;next} /box/{f=0} !f' file candy_box a orange blue red sweet_box a Jelly1 jelly2 chox_box a Snickers; MARS 

Golfing la solution fedorqui a posté

 awk 'NF==2 {f=/box c$/?0:1} f' file candy_box a orange blue red sweet_box a Jelly1 jelly2 chox_box a Snickers; MARS 

Si les données contiennent une ligne avec deux champs, la solution ci-dessus échouera.
Cela peut être une meilleure approche.

 awk '/box/ {f=/box c/?0:1} f' 

 awk '/_box [az]*/ {f=/box c/?0:1} f' 

Cela pourrait fonctionner pour vous (GNU sed):

 sed -n ':a;/box c/I{:b;n;/box/ba;bb};p' file 

S’il s’agit d’une ligne contenant la box c passez à la ligne suivante avec une box et testez-la à nouveau, sinon imprimez-la.