web-dev-qa-db-fra.com

grep - affiche les lignes jusqu'à un certain motif

Je suis sur Ubuntu 16.04 et je veux rechercher des fichiers dans les fichiers. Le fichier pourrait ressembler à ceci

if …
  SOME CODE
endif

Je peux le faire avec grep -A9 if my_file | grep -B9 endif. Cela ne fonctionne pas si la clause "if" est supérieure à 9, si plusieurs clauses "if" sont dans le même fichier et si la première commande grep contient plusieurs clauses "if". L’option -m1 dans le second grep n’aide en rien. Les clauses "if" imbriquées peuvent être ignorées. Quelqu'un a une idée, peut-être pas avec grep?

Différence à Comment puis-je grep pour plusieurs modèles sur plusieurs lignes?

  1. La question demande une solution avec grep à laquelle on a déjà répondu dans la question: grep -A9 if my_file | grep -B9 endif. La solution ne fonctionne pas dans mon cas mais fonctionnerait dans le cas de l’autre question.

  2. Les solutions grep proposées pour l’autre question ne fonctionnent pas (avec Ubuntu?): grep: ein nicht geschütztes ^ oder $ wird mit -Pz nicht unterstützt., qui est quelque chose comme grep: a not protected ^ or $ is not supported with -Pz. J'utilise les éléments suivants:

    root:/tmp# cat file
    Some text
    begin
    Some text goes here.  
    end
    Some more text 
    root:/tmp# grep -Pzo "^begin\$(.|\n)*^end$" file
    grep: ein nicht geschütztes ^ oder $ wird mit -Pz nicht unterstützt
    
  3. Les solutions proposées ne recherchent que les motifs qui commencent au début de la ligne si j'interprète correctement la solution proposée. Même si je supprime ^, la commande ne fonctionne pas.

6
musbach

Vous pouvez utiliser sedpour cela:

sed -n '/if/,/endif/p' myfile
  • -n n'imprime rien jusqu'à ce que nous le demandions
  • /if/ trouve la première ligne avec ceci
  • , continue jusqu'à ce que ...
  • /endif/ c'est la dernière ligne que nous voulons
  • paffiche les lignes correspondantes
19
Zanna

greptraditionnel est orienté ligne. Pour effectuer des correspondances sur plusieurs lignes, vous devez soit le tromper en insérant tout le fichier en lui indiquant que votre entrée est terminée par un zéro, par exemple.

grep -zPo '(?s)\nif.*\nendif' file

ou utilisez un outil plus flexible tel que pcregrepname__

pcregrep -M '(?s)\nif.*?\nendif' file

ou Perl lui-même

Perl -00 -ne 'print if m/^if.*?endif/s' file

Alternativement, pour faire correspondre structuré entrée de la même manière que grep, il y a sgrepname__

sgrep '"if" .. ("endif") containing "SOME CODE"' file
6
steeldriver

Une solution awk pourrait ressembler à: awk '/if/,/endif/' file

Bien sûr, cela ressemble à la solution avec sed.

4
user618061