Comment puis-je rechercher un motif multiligne dans un fichier?
-
02-07-2019 - |
Question
Je devais trouver tous les fichiers contenant un motif de chaîne spécifique. La première solution qui me vienne à l’esprit est d’utiliser find avec le tuyau xargs grep :
find . -iname '*.py' | xargs grep -e 'YOUR_PATTERN'
Mais si je dois trouver des modèles qui couvrent plusieurs lignes, je suis bloqué parce que vanilla grep ne peut pas trouver de modèles multilignes.
La solution
J'ai donc découvert pcregrep ce qui signifie Expressions régulières compatibles avec Perl GREP .
Par exemple, vous devez rechercher des fichiers dans lesquels la variable " _name " est immédiatement suivie de la variable " _description ":
find . -iname '*.py' | xargs pcregrep -M '_name.*\n.*_description'
Conseil: vous devez inclure le caractère de saut de ligne dans votre modèle. Selon votre plate-forme, il peut s'agir de '\ n', \ r ',' \ r \ n ', ...
Autres conseils
Pourquoi ne pas choisir awk :
awk '/Start pattern/,/End pattern/' filename
grep -P
utilise également libpcre, mais beaucoup est plus installé. Pour rechercher une section titre
complète dans un document HTML, même s'il s'étend sur plusieurs lignes, vous pouvez utiliser ceci:
grep -P '(?s)<title>.*</title>' example.html
Depuis que le projet PCRE est implémenté dans la norme perl, utilisez la documentation perl pour référence:
Voici un exemple plus utile:
pcregrep -Mi "<title>(.*\n){0,5}</title>" afile.html
Il recherche la balise de titre dans un fichier HTML même s'il s'étend sur 5 lignes au maximum.
Voici un exemple de lignes illimitées:
pcregrep -Mi "(?s)<title>.*</title>" example.html
Avec chercheur d'argent :
ag 'abc.*(\n|.)*efg'
Les optimisations de vitesse du chercheur d'argent pourraient éventuellement briller ici.
Vous pouvez utiliser l'alternative grep filtrer ici (disclaimer: je suis l'auteur).
Il prend en charge la correspondance multiligne et limite la recherche à des types de fichiers spécifiques prédéfinis:
sift -m --files '*.py' 'YOUR_PATTERN'
(recherchez dans tous les fichiers * .py le motif de regex multiligne spécifié)
Il est disponible pour tous les principaux systèmes d'exploitation. Jetez un coup d’œil à la page d'exemples pour voir comment l'utiliser pour extraire les valeurs multilignes d'un Fichier XML.
Cette réponse pourrait être utile:
Regex (grep) pour la recherche multiligne requise <> / a>
Pour rechercher récursivement, vous pouvez utiliser les drapeaux -R (récursif) et --include (modèle GLOB). Voir:
Utilisez grep --exclude / - inclure la syntaxe pour ne pas passer par grep dans certains fichiers
perl -ne 'print if (/begin pattern/../end pattern/)' filename
Utilisation de l'éditeur ex
/ vi
et option globstar (syntaxe similaire à awk
et sed
):
ex +"/string1/,/string3/p" -R -scq! file.txt
où aaa
est votre point de départ et bbb
est votre texte de fin.
Pour effectuer une recherche récursive, essayez:
ex +"/aaa/,/bbb/p" -scq! **/*.py
Remarque: pour activer la syntaxe **
, exécutez shopt -s globstar
(Bash 4 ou zsh).
@Marcin: Exemple awk non gourmand:
awk '{if (<*> ~ /Start pattern/) {triggered=1;}if (triggered) {print; if (<*> ~ /End pattern/) { exit;}}}' filename