Y at-il un caractère générique véritablement universel dans Grep? [dupliquer]

StackOverflow https://stackoverflow.com/questions/1897374

  •  19-09-2019
  •  | 
  •  

Question

    

Cette question a déjà une réponse ici:

         

question vraiment fondamentale ici. Donc, je dis qu'un point. correspond à tout caractère sauf un saut de ligne. Je cherche quelque chose qui correspond à tout caractère, y compris les sauts de ligne.

Tout ce que je veux faire est de saisir tout le texte dans une page Web entre deux chaînes spécifiques, l'en-tête de décapage et le pied de page. Quelque chose comme TEXT HEADER (. +) TEXT puis extraire FOOTER ce qui est dans les parenthèses, mais je ne peux pas trouver un moyen d'inclure tous les sauts de texte et la ligne entre tête et pied de page, est-ce sens? Merci d'avance!

Était-ce utile?

La solution

Quand je dois correspondre à plusieurs personnages, y compris les sauts de ligne, je fais:

[\s\S]*?

Note J'utilise un motif non gourmand

Autres conseils

Vous pouvez le faire avec Perl:

$ perl -ne 'print if /HEADER TEXT/ .. /FOOTER TEXT/' file.html

Pour imprimer uniquement le texte entre les délimiteurs, utilisez

$ perl -000 -lne 'print $1 while /HEADER TEXT(.+?)FOOTER TEXT/sg' file.html

Le commutateur /s rend le matcher d'expression régulière traiter la chaîne entière comme s ligne Ingle, ce qui signifie point correspond à des sauts de ligne, et /g signifie correspondre autant de fois que possible.

Les exemples ci-dessus supposent que vous êtes sur les fichiers de démarrage HTML sur le disque local. Si vous avez besoin de les chercher d'abord, utilisez get de LWP::Simple :

$ perl -MLWP::Simple -le '$_ = get "http://stackoverflow.com";
                          print $1 while m!<head>(.+?)</head>!sg'

S'il vous plaît noter que le HTML d'analyse syntaxique des expressions régulières comme ci-dessus ne fonctionne pas dans le cas général! Si vous travaillez sur un scanner rapide et sale, très bien, mais pour une application qui a besoin pour être plus robuste, utilisez un véritable analyseur.

Par définition, grep recherche les lignes qui correspondance; il lit une ligne, voit si elle correspond, et imprime la ligne.

Une façon possible de faire ce que vous voulez est avec sed:

sed -n '/HEADER TEXT/,/FOOTER TEXT/p' "$@"

Cette affiche de la première ligne qui correspond à « TEXT HEADER » à la première ligne qui correspond TEXT FOOTER ', puis itère; l'opération « -n » arrête la valeur par défaut 'imprimer chaque ligne. Cela ne fonctionne pas bien si le texte apparaît en-tête et pied de page sur la même ligne.

Pour faire ce que vous voulez, je serais probablement utiliser perl (mais vous pouvez utiliser Python si vous préférez). Je considère siphonage le fichier entier, puis utiliser une expression régulière dûment qualifié pour trouver les parties correspondantes du fichier. Cependant, le Perl en une ligne donnée par « @gbacon » est une translittération presque exacte en Perl du script sed ci-dessus et est plus propre que siphonage.

La page de manuel de grep dit:

  

grep, egrep, fgrep, rgrep - lignes d'impression correspondant à un motif

grep est pas fait pour correspondre plus d'une seule ligne. Vous devriez essayer de résoudre cette tâche avec perl ou awk.

Comme cela est taggés avec « BBEdit » et supporte BBedit Pattern Perl Modificateurs-style vous pouvez autoriser le point pour correspondre avec le commutateur linebreaks (? S)

(? S).

correspond à tout caractère. Et oui, (? S). + correspondra à l'ensemble du texte.

Comme indiqué ailleurs, grep travaillera pour des trucs en ligne unique.

Pour plusieurs lignes (en rubis avec Regexp :: multiligne, ou en python, awk, sed, peu importe), "\ s" devrait également saisir les sauts de ligne, de sorte que

HEADER TEXT(.*\s*)FOOTER TEXT 

pourrait fonctionner ...

Voici une façon de le faire avec gawk, si vous avez

awk -vRS="FOOTER" '/HEADER/{gsub(/.*HEADER/,"");print}' file
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top