Comment extraire de la chaîne à la suite d'un motif avec grep, regex ou perl
J'ai un fichier qui ressemble à quelque chose comme ceci:
<table name="content_analyzer" primary-key="id">
<type="global" />
</table>
<table name="content_analyzer2" primary-key="id">
<type="global" />
</table>
<table name="content_analyzer_items" primary-key="id">
<type="global" />
</table>
J'ai besoin d'extraire quoi que ce soit dans les citations qui suivent name=
, c'est à dire, content_analyzer
, content_analyzer2
et content_analyzer_items
.
Je le fais sur une machine Linux, une solution à l'aide de sed, perl, grep bash est très bien.
- pas besoin d'être timide, bienvenue ici!
- Je pense qu'il serait erroné de ne pas faire un lien vers stackoverflow.com/questions/1732348/...
- Merci à tous pour les commentaires utiles. Je m'excuse pour le XML n'est pas correctement formaté. J'ai supprimé quelques balises pour la simplification.
Vous devez vous connecter pour publier un commentaire.
Car vous avez besoin de faire correspondre le contenu sans l'inclure dans le résultat (doit
match
name="
mais ce n'est pas le résultat souhaité) une certaine forme dezéro-largeur de contrepartie ou un groupe de capture est nécessaire. Cela peut être fait
facilement avec les outils suivants:
Perl
Avec Perl, vous pouvez utiliser les
n
option en boucle, ligne par ligne et à imprimerle contenu d'une capture d'un groupe si elle correspond à:
GNU grep
Si vous avez une version améliorée de grep, tels que GNU grep, vous pouvez avoir
le
-P
disponible en option. Cette option permettra à Perl-comme regex,vous permettant d'utiliser
\K
qui est une abréviation lookbehind. Il sera réinitialiséle match position, donc rien avant de largeur nulle.
La
o
option permet de grep imprimer uniquement le texte correspondant, au lieu de latoute la ligne.
Vim - Éditeur De Texte
Un autre moyen est d'utiliser un éditeur de texte directement. Avec Vim, l'un des
différentes façons d'y parvenir serait de supprimer des lignes, sans
name=
puis extrayez-en le contenu à partir de la résultante des lignes:Standard grep
Si vous n'avez pas accès à ces outils, pour une raison quelconque, quelque chose
similaire pourrait être atteint avec la norme grep. Cependant, sans la regarder
autour de il faudra un peu de nettoyage plus tard:
D'une note sur l'enregistrement des résultats
Dans l'ensemble de la commande ci-dessus, les résultats seront envoyés à
stdout
. C'estimportant de se rappeler que vous pouvez toujours enregistrer eux par des conduites à un
fichier en ajoutant:
à la fin de la commande.
grep
):grep -Po '.*name="\K.*?(?=".*)'
.*
de côté, j'espère que vous ne vous fâchez pas avec moi. Je voudrais vous demander, voyez-vous des avantages de l'onu-gourmand match de plus de "tout sauf"
"? Ne prenez pas cela comme un combat, je suis juste curieux et je ne suis pas une regex expert. Aussi, le\K
astuce, vraiment sympa. Merci Dennis..*
, vous pouvez le fairegrep -Po '(?<=name=").*?(?=")'
. Le\K
peut être utilisé pour la sténographie, mais c'est vraiment nécessaire seulement si le match à sa gauche est de longueur variable. Dans ce cas, la raison de l'utilisation lookarounds est assez évident. Moins gourmand opérations de regarder un peu plus propre ([^"]*
contre.*?
et vous n'avez pas à répéter le point d'ancrage de caractère. Je ne sais pas à propos de la vitesse. Cela dépend beaucoup du contexte, je pense. J'espère que c'est utile.\K
(après des recherches sur elle) et retiré la.*
était le même: faire paraître jolie (plus simple). Et je n'ai jamais pensé à l'aide de.*?
au lieu de la "méthode traditionnelle" j'ai appris à partir de quelque part. Mais l'onu-gourmand ici qui fait vraiment de sens. Merci Dennis, meilleurs voeux.^
qui signifie qu'il correspond à tout sauf à son contenu. Donc[^"]
entend de tout caractère qui n'est pas une citation. Je n'ai pas l'utiliser dans la dernière réponse en faveur de la pas prête version,.*?
. Le précédent était gourmand, j'ai donc utilisé cette classe pour correspondre à tout, pas une citation avec l'intention de s'arrêter sur la première citation, qui est la même que la correspondance de rien "ungreedly" jusqu'à un devis. Espérons que cela aide à comprendre, et laissez-moi savoir si je peux mieux clarifier certaines partie.grep
via homebrew et l'utiliser à la place de celui par défaut. Il devrait fonctionner.grep -Po 'look-ahead \K capture'
fait ma journée. Slick.L'expression régulière serait:
Puis le groupement serait dans le \1
Si vous utilisez Perl, télécharger un module de parser le XML: XML::Simple, XML::Twig, ou XML::LibXML. Ne pas ré-inventer la roue.
<type="global"
par exemple), de sorte que la plupart des parsers XML simplement se plaindre et de mourir.Un analyseur HTML doit être utilisé à cette fin plutôt que les expressions régulières. Un programme en Perl qui permet d'utiliser
HTML:: "TreeBuilder"
:Programme
Sortie
cela pourrait le faire:
Voici une solution à l'aide de HTML tidy & xmlstarlet:
Oups, la dsi doit précéder la coquette commande de cours:
Si la structure de votre xml (ou le texte en général) est fixe, le plus simple est d'utiliser
cut
. Pour votre cas spécifique: