1
votes

comment obtenir deux matchs par ligne

J'ai besoin d'un mot après PgTrx et un mot après Statusdescription

exemple de journal:

status = 1 & newMainBalance = 5486 & serviceAmount = 700 & ExternalTrxId = asdf & PgTrxId = tfpsadf & amount = 0 & statusDescription = Failed & customerCode = 1.1 & newDedicatedBalance = 0 & secureHash = 56a7sdyf & PaidAmount = 1000 & responseMsg =% a1% a1% A1 (1286_HT) "" - "" https://example.com.eg?statusDescription=Failed&externalTrxId=123&status=203&secureHash=asdf&pgTrxId=asdf

J'ai essayé ce qui suit mais je n'obtiens qu'un mot après statusdescription :

statusDescription=Failed

je veux obtenir le résultat comme ci-dessous.

PgTrxId=tfpsadf&statusDescription=Failed

mais j'ai seulement

perl -ne 'foreach my $p (split(/&/)) { if ($p =~ /statusDescription(=.*)/) { print "$1\n"; last } }'

cat file.txt | perl -ne 'forea ch my $p (split(/&/)) { if ($p =~ /statusDescription(=.*)/) { print "$1\n"; last } }'


2 commentaires

Votre code contient une erreur de syntaxe ( forea ch ). Si vous corrigez cela, cela ne produit pas le résultat que vous réclamez.


Voulez-vous faire correspondre PgTrxId ou PgTrx ?


3 Réponses :


3
votes

Ne vous embêtez pas avec Split. Analysez la ligne entière en un hachage, puis sélectionnez les clés que vous voulez:

   my @list_of_wanted_things; 
   foreach my $word ( @wanted ) {
      push ( @list_of_wanted_things,  "$word=$param{$word}" ); 
   }
   print join "&", @list_of_wanted_things;

Si vous voulez cela comme une seule ligne:

perl -ne '%p = m/(\w+)=(\w+)/g; print join ( "&", map { "$_=$p{$_}" } ) qw ( PgTrxId statusDescription ),"\n"' 

J'ai utilisé map ici par souci de concision, car c'est utile dans une seule ligne, mais c'est fonctionnellement équivalent à:

#!/usr/bin/env perl

use strict;
use warnings;

use Data::Dumper;

my @wanted = qw ( PgTrxId statusDescription );

while (<DATA>) {
   my %param = m/(\w+)=(\w+)/g;
   print Dumper \%param;

   print join ( "&", map { "$_:$param{$_}" } @wanted ),"\n";
}



__DATA__
status=1&newMainBalance=5486&serviceAmount=700&ExternalTrxId=asdf&PgTrxId=tfpsadf&amount=0&statusDescription=Failed&customerCode=1.1&newDedicatedBalance=0&secureHash=56a7sdyf&paidAmount=1000&responseMsg=%a1%a1%A1(PG_ID)&language=enHTTP/1.1"200186243**1/1210669**1"-""-""-""https://example.com.eg?statusDescription=Failed&externalTrxId=123&status=203&secureHash=asdf&pgTrxId=asdf


1 commentaires

Cela fonctionne pour les deux paramètres qui nous sont spécifiquement demandés ici. Mais pour certains des autres paramètres, vous devez changer le (\ w +) qui capture la valeur.



1
votes

Deux choses évidentes que vous voudriez changer:

  • Recherchez "PgTrxId" ainsi que "statusDescription"
  • Supprimez le dernier pour qu'il ne s'arrête pas une fois qu'il en a trouvé un.

J'ai également utilisé (?: ...) pour regrouper les termes de recherche sans les capturer.

perl -ne 'foreach my $p (split(/&/)) { if ($p =~ /(?:statusDescription|PgTrxId)(=.*)/) { print "$1\n" } }'

Mais je préfère de loin la solution de Sobrique .


0 commentaires

0
votes

si vos données sont dans le fichier 'd',

perl -ne '@s = /\b(PgTrxId=[^&]+)|(&statusDescription=[^&]+)/xg;print @s' d

le résultat est dans la variable tableau @s


0 commentaires