2012-11-23 1 views
5

Je suis novice en matière d'expressions régulières, mais je pense que les gens ici peuvent me donner des informations précieuses. J'utilise le filtre logstash grok dans lequel je ne peux fournir que des expressions régulières.Expression régulière pour extraire une partie d'un chemin de fichier à l'aide du filtre logstash grok

J'ai une chaîne comme ce

/app/webpf04/sns882A/snsdomain/logs/access.log 

Je veux utiliser une expression régulière pour obtenir la sns882A partie de la chaîne, qui est la sous-chaîne après le troisième «/», comment puis-je faire?

Je suis limité à regex car grok n'accepte que regex. Est-il possible d'utiliser regex pour cela?

Répondre

2

pour votre regex:

/\w*\/\w*\/(\w*)\/ 

Vous pouvez également tester avec: http://www.regextester.com/

par googler testeur de regex, vous pouvez avoir différentes interface utilisateur.

+0

De http: //www.regextester.com/ça ne me donne aucune correspondance, j'ai essayé http://gskinner.com/RegExr/ pas de résultat là aussi ... – flyasfish

+0

Cette solution repose sur des noms de répertoires et de fichiers toujours constitués de caractères alphanumériques ou de traits de soulignement. En particulier, il peut n'y avoir aucun espace dans le chemin – Borodin

+0

la correspondance est basée sur l'index 0. Vous pouvez également voir: 1: (sns882A), ce qui signifie que c'est le premier match. – junky

0

Voilà comment je le ferais en Perl:

my ($name) = ($fullname =~ m{^(?:/.*?){2}/(.*?)/}); 

EDIT: Si votre cadre ne prend pas en charge Perl-ish groupes non-regroupement (?:xyz), ce regex devrait travailler à la place:

^/.*?/.*?/(.*?)/ 

Si vous êtes préoccupé par la performance de .*?, cela fonctionne ainsi:

^/[^/]+/[^/]+/([^/]+)/ 

Une note de plus: Toutes les expressions rationnelles ci-dessus correspondent à la chaîne /app/webpf04/sns882A/.

Mais la chaîne correspondante est complètement différente du premier groupe correspondant, qui est sns882A dans les trois cas.

+0

Quand j'essaye^(?: /.*?) {2}/(. *?)/Part sur http://gskinner.com/RegExr/, il correspond à/app/webpf04/sns882A/ – flyasfish

+0

Avez-vous essayé en Perl ou en Python? Je l'ai fait, et cela fonctionne – mvp

+0

Vous devriez utiliser '(?:/[^ /] *)'. Sinon, votre regex peut prendre un * long * temps pour décider qu'il ne correspond pas – Borodin

0

Si vous êtes en effet utilisez Perl vous devez utiliser le module File::Spec comme celui-ci

use strict; 
use warnings; 

use File::Spec; 

my $path = '/app/webpf04/sns882A/snsdomain/logs/access.log'; 
my @path = File::Spec->splitdir($path); 

print $path[3], "\n"; 

sortie

sns882A 
+0

Je ne peux utiliser aucune langue, cela fait partie de la configuration de logstash-grok dans laquelle je ne peux fournir que des expressions. – flyasfish

5

Oui, vous pouvez utiliser une expression régulière pour obtenir ce que vous voulez via grok:

/[^/]+/[^/]+/(?<field1>[^/]+)/ 
+0

Je sais que cette réponse est trop tardive, mais +1 de toute façon pour être la première * bonne * réponse. C'est une regex autonome (aucun autre code et aucun délimiteur) qui utilise la capture nommée pour les parties qu'elle est censée extraire. –

0

Même réponse mais un petite correction de bogue. Si vous ne spécifiez pas^au démarrage, il ira pour la prochaine correspondance (essayez les chemins plus longs en ajoutant plus/pour l'entrée.). Pour le réparer, ajoutez juste^au début comme ceci.^signifie le début de la ligne d'entrée. Enfin, group1 est votre réponse. Si vous utilisez des chemins d'URI, utilisez ci-dessous (il gérera le chemin ainsi que l'URI).

^.*?/[^/]+/[^/]+/([^/]+)/ 
Questions connexes