GNU/Linux >> Tutoriels Linux >  >> Linux

Imprimer des lignes entre le motif de début et de fin, mais si le motif de fin n'existe pas, ne pas imprimer

Vous pouvez le faire comme suit :

$ sed -e '
    /BEGIN/,/END/!d
    H;/BEGIN/h;/END/!d;g
' inp

Comment cela fonctionne, pour la plage de lignes de début/fin, il les stocke dans l'espace de maintien. Supprime ensuite jusqu'à ce que vous rencontriez la ligne END. À quel point nous rappelons ce qui est en attente. OTW, nous n'obtenons rien.HTH.


cat input |
sed '/\*\*\*\*\* BEGIN \*\*\*\*\*/,/\*\*\*\*\* END *\*\*\*\*/ p;d' | 
tac |
sed '/\*\*\*\*\* END \*\*\*\*\*/,/\*\*\*\*\* BEGIN *\*\*\*\*/ p;d' |
tac

Cela fonctionne en ayant tac inverser les lignes pour que sed peut trouver les deux délimiteurs dans les deux ordres.


Avec pcregrep :

pcregrep -M '(?s)BEGIN.*?END'

Cela fonctionne également si BEGIN et END sont sur la même ligne, mais pas dans des cas comme :

BEGIN 1 END foo BEGIN 2
END

pcregrep attrape le premier BEGIN 1 END , mais pas le second.

Pour les gérer, avec awk , vous pourriez faire :

awk '
  !inside {
    if (match($0, /^.*BEGIN/)) {
      inside = 1
      remembered = substr($0, 1, RLENGTH)
      $0 = substr($0, RLENGTH + 1)
    } else next
  }
  {
    if (match($0, /^.*END/)) {
      print remembered $0
      if (substr($0, RLENGTH+1) ~ /BEGIN/)
        remembered = ""
      else
        inside = 0
    } else
      remembered = remembered $0 ORS
  }'

Sur une entrée comme :

a
BEGIN blah END BEGIN 1
2
END
b
BEGIN foo END
c
BEGIN
bar
END BEGIN
baz END
d
BEGIN
xxx

Cela donne :

BEGIN blah END BEGIN 1
2
END
BEGIN foo END
BEGIN
bar
END BEGIN
baz END

Les deux ont besoin de tout stocker du BEGIN au END suivant en mémoire. Donc si vous avez un gros fichier dont la première ligne contient BEGIN mais sans END, tout le fichier sera stocké en mémoire pour rien.

Le seul moyen de contourner cela serait de traiter le fichier deux fois, mais bien sûr, cela ne peut être fait que lorsque l'entrée est un fichier normal (pas un tube par exemple).


Linux
  1. open() en Python ne crée pas de fichier s'il n'existe pas

  2. wc -l ne compte PAS le dernier du fichier s'il n'a pas de caractère de fin de ligne

  3. docker images montre l'image, docker rmi dit qu'aucune image ou référence n'existe pas

  4. La correspondance de modèle ne fonctionne pas dans le script bash

  5. Le point de montage n'existe pas, malgré sa création

Linux – /sbin/init n'existe pas ?

Ajouter une ligne à un fichier uniquement s'il n'existe pas déjà

Pourquoi Tomcat fonctionne-t-il avec le port 8080 mais pas 80 ?

l'émulateur android ne démarre pas, avd

Linux gratuit montre une utilisation élevée de la mémoire, mais pas top

Supprimer les fichiers qui commencent par mais ne contiennent pas