2011-02-10 4 views
2

J'utilise perl pour vérifier une entrée de texte pour un motif regex, mais un motif ne fonctionne pas avec perl -pe.perl -pe problème regex

modèle suivant ne fonctionne pas avec l'appel de commande:

s![a-zA-Z]+ +(?:.*?)/(?:.*)Comp-(.*)/.*!$1! 

J'utilise le shell linux. À la suite de l'appel que j'utilise pour tester mon regex:

cat test | perl -pe 's![a-zA-Z]+ +(?:.*?)/(?:.*)Comp-(.*)/.*!$1!' 

Test du fichier:

A MaintanceGie?\195?\159mannFlock/System/Comp-Database.cpp 
A MaintanceGie?\195?\159mannFlock/System/Comp-Cache/abc.h

Résultat:

A MaintanceGie?\195?\159mannFlock/System/Comp-Database.cpp 
Cache

Comment puis-je supprimer le premier résultat?

Merci pour tout conseil.

+0

shell que vous utilisez? Quelle est votre contribution? Quelle est votre sortie attendue? –

+0

Informations ajoutées. – CSchulz

+0

Que diable est ce backslash wacky octal - er, je veux dire ** non-octal ** - gunk là ?? Sûr ressemble à un problème d'encodage pour moi! – tchrist

Répondre

2
$ cat input 
A MaintanceGie?\195?\159mannFlock/System/Comp-Database.cpp 
A MaintanceGie?\195?\159mannFlock/System/Comp-Cache/abc.h 

$ perl -ne 'print if s![a-zA-Z]+ +(?:.*?)/(?:.*)Comp-(.*)/.*!$1!' input 
Cache
3

Cette dernière barre oblique après "Comp - (. *)" Peut être ce qui se passe. Le contenu de votre fichier dans la "base de données" n'a pas de barre oblique. Essayez de remplacer Comp-(.*)/.* par Comp-(.*)[/.].* afin de pouvoir faire correspondre le sous-répertoire ou l'extension de fichier.

+0

Il y avait une erreur dans mes données. Mais pourquoi obtenir la ligne entière, quand ne correspond pas? – CSchulz

+0

@ H3llGhost: parce que le substitut n'est pas fait. – Toto

1

Le problème est dans le dernier caractère barre oblique dans l'expression régulière. Au lieu d'échapper le point, c'est juste un caractère barre oblique, qui manque dans la chaîne d'entrée. Essayez ceci:

s![a-zA-Z]+ +(?:.*?)/(?:.*)Comp-(.*)[./].*!$1! 

Edit: Mise à jour pour correspondre à de nouvelles données d'entrée et a ajouté une autre option:

D'autre part, votre regex de remplacement pourrait être remplacé par quelque chose comme:

perl -ne 'print "$1\n" if /Comp-(.*?)[.\/]/' 

Ensuite, il n'est pas nécessaire d'analyser la ligne complète avec tout ce qu'elle contient.

+0

Il pourrait également ne pas blesser d'utiliser '\ s +' au lieu de '+'. –

+0

Il y a eu une erreur dans mes données. Mais pourquoi obtenir la ligne entière, quand ne correspond pas? Que fait ** \ s + **? Je ne l'ai jamais entendu. – CSchulz

+0

Parce que vous utilisez s /// operator pour faire regex-replace. Si regex ne correspond pas, aucun remplacement n'est effectué. – bvr

1

\ s correspond à un espace (espaces, tabulations et sauts de ligne) et '+' à un ou plusieurs caractères. Dans ce cas, '\ s +' signifierait rechercher un ou plusieurs espaces.

cat test 
A MaintanceGie?\195?\159mannFlock/System/Comp-Database.cpp 
A MaintanceGie?\195?\159mannFlock/System/Comp-Cache/abc.h 

perl -ne 'print "$1\n" if /\w+?\d+?\d+\w+\/\w+\/Comp-(\w+)[\/]/' test