253 votes

Regex (grep) pour la recherche multiligne nécessaire

Double Possible:
Comment puis-je rechercher une multiligne motif dans un fichier ? Utilisation pcregrep

Je suis à court d'un grep trouver tout *.fichier sql qui a le mot select suivi par le mot customerName suivi par le mot from. Cette instruction select peut s'étendre sur plusieurs lignes et peut contenir des tabulations et retours à la ligne.

J'ai essayé quelques variations sur les points suivants:

$ grep -liIr --include="*.sql" --exclude-dir="\.svn*" --regexp="select[a-zA-Z0-
9+\n\r]*customerName[a-zA-Z0-9+\n\r]*from"

Cela, toutefois, ne s'exécute jamais. Quelqu'un peut m'aider avec la syntaxe correcte s'il vous plaît?

559voto

albfan Points 2333

Sans avoir besoin d'installer le grep variante pcregrep, vous pouvez le faire de plusieurs lignes de recherche avec grep.

$ grep -Pzo "(?s)^(\s*)\N*main.*?{.*?^\1}" *.c

Explication:

-P activer perl-regexp pour grep (une puissante extension de régulièrement des extensions)

-z supprimer le saut de ligne à la fin de la ligne, subtituting pour caractère null. C'est, grep sait où la fin de la ligne, mais voit l'entrée comme une grande ligne.

-o imprimer uniquement de la correspondance. Parce que nous utilisons -z, le fichier entier est comme une seule grande ligne, donc si il ya un match, le fichier sera imprimé; de cette manière, il n'allons pas le faire.

Dans regexp:

(?s) activer PCRE_DOTALL, ce qui signifie qu' . trouve n'importe quel caractère ou de saut de ligne

\N trouver de tout, sauf de saut de ligne, même avec PCRE_DOTALL activé

.*? trouver . dans nongreedy mode, qui est, s'arrête dès que possible.

^ trouver début de ligne

\1 référence arrière à premier groupe (\s*) C'est d'essayer de trouver de même indentation de la méthode

Comme vous pouvez l'imaginer, cette recherche imprime la méthode main dans un C (*.c) du fichier source.

188voto

Amit Points 789

Je ne suis pas très bon dans grep. Mais votre problème peut être résolu à l’aide de la commande AWK . Il suffit de voir

Le code ci-dessus entraînera de la première occurrence de jusqu'à la première séquence de . Maintenant, vous devez vérifier si les déclarations retournées ont `` ou non. Pour cela, vous pouvez rediriger le résultat. Et awk ou grep peut réutiliser.

8voto

Jonathan Leffler Points 299946

Votre problème fondamental est qu' grep fonctionne une ligne à la fois - de sorte qu'il ne peut pas trouver une instruction SELECT, réparties à travers les lignes.

Votre deuxième problème est que la regex que vous utilisez n'aura pas à composer avec la complexité de ce qui peut apparaître entre les SÉLECTIONNER et DE - en particulier, il omet les virgules, les points (périodes) et les blancs, mais aussi des citations et tout ce qui peut être à l'intérieur d'une chaîne de caractères entre guillemets.

Je serais probablement aller avec un Perl-base de solution, ayant Perl lire "paragraphes" à un moment et en appliquant une regex. L'inconvénient est d'avoir à traiter avec la recherche récursive - il existe des modules pour le faire, bien sûr, y compris le noyau du module File::Find.

Dans les grandes lignes, pour un seul et même fichier:

$/ = "\n\n";    # Paragraphs

while (<>)
{
     if ($_ =~ m/SELECT.*customerName.*FROM/mi)
     {
         printf file name
         go to next file
     }
}

Qui doit être enveloppé dans un sous c'est alors invoquée par les méthodes de File::Find.

3voto

splash Points 8499

N’est pas `` uniquement pour la recherche de la seule ligne ? Cette question est peut-être utile pour vous : Comment puis-je Rechercher un modèle multiligne dans un fichier ?

2voto

Andy Lester Points 34051

En dehors de l’expression régulière, vous pouvez regarder dans l' accusé de réception, qui exclut automatiquement les répertoires .svn pour vous, et qui peut limiter à seulement les fichiers .sql--SQL.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X