Supprimez la ligne contenant une certaine chaîne et la ligne suivante

Jutilise ceci

cat foo.txt | sed "/bar/d"

pour supprimer les lignes contenant la chaîne bar dans le fichier.

Je voudrais cependant supprimer ces lignes et la ligne directement après . De préférence dans sed, awk ou dans un autre outil disponible dans MinGW32.

Cest une sorte dinverse de ce que je peux obtenir dans grep avec -A et -B pour imprimer également les lignes correspondantes sous forme de lignes avant / après la ligne correspondante.

Y a-t-il un moyen simple dy parvenir?

Commentaires

  • Juste pour information: Je ‘ m analyse les journaux dans lesquels les entrées sont à deux lignes. Je veux donc trouver une entrée correspondant au modèle et la supprimer ainsi que la ligne suivante. Par conséquent, je nai ‘ pas besoin de gérer des lignes de correspondance consécutives, mais merci quand même pour lexhaustivité de vos réponses!

Réponse

Si vous avez GNU sed (donc Linux ou Cygwin non embarqué):

sed "/bar/,+1 d" 

Si vous avoir bar sur deux lignes consécutives, cela supprimera la deuxième ligne sans lanalyser. Par exemple, si vous avez un fichier de 3 lignes bar / bar / foo, la ligne foo restera.

Commentaires

  • +1 pour la longueur 🙂 Dans mon cas exemple Je nai pas ‘ Jai des bar consécutifs, donc celui-ci est très facile à retenir.
  • sed '/bar/d' si vous voulez simplement  » Supprimer la ligne contenant une certaine chaîne  » et pas le suivant.
  • Si je veux supprimer toutes les lignes après les maths, alors?
  • @Pandya Cela ‘ est différent. Vous pouvez utiliser par ex. sed '/math/q'
  • @ A.K. Si vous souhaitez simplement supprimer la ligne correspondante, ‘ est encore plus simple: sed '/bar/d'

Réponse

Si bar peut apparaître sur des lignes consécutives, vous pouvez faire:

awk "/bar/{n=2}; n {n--; next}; 1" < infile > outfile 

qui peut être adapté pour supprimer plus de 2 lignes en changeant les 2 ci-dessus avec le nombre de lignes à supprimer, y compris celle correspondante.

Sinon, il « est facile à faire dans sed avec la @MichaelRollins » solution ou:

sed "/bar/,/^/d" < infile > outfile 

Commentaires

  • Lautre avantage de la solution AWK est que je peux remplacer /bar/ par /bar|baz|whatever/. Dans sed cette syntaxe ne semble pas ‘ fonctionner.
  • @ jakub.g, jai GNU sed ( v4.4 maintenant). Pas sûr des autres. Ce que je sais, cest quil utilise la syntaxe dexpression régulière  » basic  » par défaut, cest pourquoi votre exemple na pas ‘ t travailler. Pour obtenir ce que vous voulez, vous pouvez soit placer une barre oblique inverse devant chaque ligne verticale, soit demander à sed dutiliser  » extended  » expressions régulières. Plus dinformations ici: gnu.org/software/sed/manual/html_node/… . Veuillez noter que cela sapplique également à grep. Voici ‘ mon propre exemple de travail: echo $'0a\n1b\n2c' | sed '/0a\|1b/d'.

Réponse

Je ne parle pas couramment sed, mais cest facile de le faire dans awk:

awk "/bar/{getline;next} 1" foo.txt 

Le awk script lit: pour une ligne contenant bar, récupérez la ligne suivante (getline), puis ignorez tout traitement ultérieur (suivant). Le motif 1 à la fin imprime les lignes restantes.

Mise à jour

Comme indiqué dans le commentaire, la solution ci-dessus ne fonctionnait pas avec bar. Voici une solution révisée, qui en tient compte:

awk "/bar/ {while (/bar/ && getline>0) ; next} 1" foo.txt 

Nous continuons maintenant à lire pour sauter toutes les / bar / lignes.

Commentaires

  • Pour répliquer grep -A 100%, vous devez également gérer nimporte quel nombre de lignes correctement (en supprimant le bloc entier et 1 ligne après).

Réponse

Pour ce faire, vous souhaiterez utiliser les capacités de script de sed.

$ sed -e "/bar/ { $!N d }" sample1.txt 

Exemple de données:

$ cat sample1.txt foo bar biz baz buz 

La commande « N » ajoute la ligne dentrée suivante dans lespace de motif. Ceci combiné avec la ligne de la correspondance de motif (/ bar /) sera les lignes que vous souhaitez supprimer. Vous pouvez alors supprimer normalement avec la commande « d ».

Commentaires

  • Comment taper une nouvelle ligne dans la console? Ou est-ce uniquement un script?
  • @ jakub.g: avec GNU sed: sed -e '/bar/{N;d}' sample1.txt

Réponse

Si une ligne immédiatement après une correspondance doit être supprimée, alors votre programme sed devra considérer des correspondances consécutives. En dautres termes, si vous supprimez une ligne après une correspondance qui correspond également, vous devriez probablement supprimer la ligne qui suit également.

Elle est implémentée assez simplement – mais vous devez regarder un peu en arrière .

printf %s\\n 0 match 2 match match \ 5 6 match match match \ 10 11 12 match 14 15 | sed -ne"x;/match/!{g;//!p;}" 

 0 6 11 12 15  

Cela fonctionne en permutant les espaces dattente et de motif pour chaque ligne lue – de sorte que la dernière ligne puisse être comparée au courant à chaque fois. Ainsi, lorsque sed lit une ligne, il échange le contenu de ses tampons – et la ligne précédente est alors le contenu de son tampon dédition, tandis que la ligne courante est mise en espace dattente.

Donc sed vérifie la ligne précédente pour une correspondance avec match , et si sa ! introuvable les deux expressions de la { function } sont exécutées. sed g et lespace de maintien en écrasant lespace de motif – ce qui signifie que la ligne actuelle est alors à la fois dans les espaces de maintien et de motif – puis il // le vérifiera pour une correspondance avec sa dernière expression régulière compilée – match – et si il nest pas match il est p imprimé.

Cela signifie quune ligne nest imprimée que si elle ne le fait pas match et la ligne immédiatement précédente ne le fait pas match . Il évite également tout échange inutile pour les séquences de match es.

Si vous vouliez une version qui pourrait supprimer un nombre arbitraire de lignes survenant après un match il faudrait un peu plus de travail:

printf %s\\n 1 2 3 4 match \ match match 8 \ 9 10 11 12 13 \ 14 match match \ 17 18 19 20 21 | sed -net -e"/match/{h;n;//h;//!H;G;s/\n/&/5;D;}" -ep 

. .. remplacer le 5 par le nombre de lignes (y compris la ligne correspondante) que vous souhaitez supprimer …


1 2 3 4 12 13 14 21 

Laisser un commentaire

Votre adresse e-mail ne sera pas publiée. Les champs obligatoires sont indiqués avec *