web-dev-qa-db-fra.com

Groupe multi-lignes capturant entre accolades

J'ai quelque chose comme ça dans un fichier testtt:

{It captures this! }
// question: 2572410  name: Question 2

::Question 2::[html] Is it going to be -40 tomorrow?

{
It can't
capture this!!! why?
}

quand je fais:

grep -o '{\([^}]*\)}' testttt

Il ne peut pas capturer les accolades multilignes. Toute aide pour le modifier de manière à capturer les deux serait appréciée!

PS J'ai également testé la solution donnée à partir de: Comment puis-je grep pour plusieurs modèles sur plusieurs lignes? et cela donne l'erreur suivante:

grep: unescaped ^ or $ not supported with -Pz

Vous pouvez trouver le fichier texte de la sortie et le contenu du fichier ici

1
Farhad

Par défaut, grep lit et traite des lignes simples.

Dans les versions plus récentes de grep, vous pouvez utiliser l'option -z pour lui demander de considérer son entrée comme étant séparée de null au lieu de séparer de nouvelle ligne; comme votre entrée n'a pas de terminaisons nulles, c'est essentiellement équivalent au mode 'Slurp' de Perl. Alors tu pourrais faire

$ grep -zPo '{[^}]*}' testttt
{It captures this! }
{
It can't
capture this!!! why?
}

ou, plus finement, en utilisant un .*? match non-glouton avec (?s) pour inclure des nouvelles lignes dans .

$ grep -zPo '(?s){.*?}' testttt
{It captures this! }
{
It can't
capture this!!! why?
}

Sinon, si pcregrep est disponible,

$ pcregrep -Mo '(?s){.*?}' testttt
{It captures this! }
{
It can't
capture this!!! why?
}
4
steeldriver

Afin de déclencher une recherche multiligne avec grep, vous devez ajouter quelques options supplémentaires, alors essayez:

 grep -Pzo '(?s){.*?}' testttt

La solution avec une explication de Nice peut être trouvée (et est volée :)) de stackoverflow .

Si vous avez pcregrep vous le trouverez peut-être plus utile dans le cas général car il supporte Perl 5 regex.

2