9
votes

Comment utiliser Perl comme SED?

J'ai un fichier qui a des entrées telles que

--ERROR--- Failed to execute the command with employee Name="shayam" Age="34"

--Successfully executed the command with employee Name="ram" Age="55"

--ERROR--- Failed to execute the command with employee Name="sam" Age="23"

--ERROR--- Failed to execute the command with employee Name="yam" Age="3"


0 commentaires

6 Réponses :


7
votes

Votre titre le rend pas clair. Quoi qu'il en soit ...

while(<>) {
 next if !/^--ERROR/;
 /Name="([^"]+)"\s+Age="([^"]+)"/;
 print $1, "  ", $2, "\n";
}


2 commentaires

Dans quel sens s'agit-il d'utiliser Perl comme SED? Ceci utilise Perl comme Perl . Je préfère l'invocation dans une réponse différente ci-dessous.


Vous préférez, et je devrais me soucier de ... Le point n'était pas d'accord avec vous et cela ferme le problème et signale votre commentaire comme non pertinent. De plus, étant donné que d'autres personnes devant vous, n'ont pas compris le sentiment plus vaste, plus faible, pas littéral de l'expression "comme SED" utilisé par l'OP dans le titre. Ce n'est pas ma faute. Chaque réponse peut toujours être rendue mieux, bien sûr, mais l'op était d'accord avec cela rapidement, donc pour moi, c'est fini. Les autres besoins peuvent être satisfaits par des réponses mieux (dans votre humble avis). (BTW j'ai souvent utilisé SED -f puisque l'édition compliquée peut être difficile à faire comme Onliner-était que j'utilisais SED comme Perl ??)



0
votes

Voir les commentaires:

my @a = <>; # Reading entire file into an array
chomp @a;   # Removing extra spaces
@a = grep {/ERROR/} @a; # Removing lines that do not contain ERROR
# mapping with sed-like regexp to keep only names and ages :
@a = map {s/^.*Name=\"([a-z]+)\" Age=\"([0-9]+)\".*$/$1 $2/; $_} @a; 
print join " ",@a; # print of array content


4 commentaires

Je recommanderais de tout lire en un seul tableau, puis de le traiter. Il suffit de lire la ligne de ligne.


Ne le prenez pas pour vous, Matthew, mais puis-je demander pourquoi?


Si vous avez un fichier plus grand que votre RAM, votre système est suspendu. C'est pourquoi. Mais plus important encore, vous n'avez tout simplement pas besoin de stocker tout le fichier dans un tableau - stocker la ligne actuelle dans une variable Single suffirait. Ne serait-ce pas? :) ou mieux, utilisez simplement $ _.


Eh bien, peut-être que je me trompe, mais en cas de gros fichier, j'utilise Tie :: Fichier. J'ai été confronté à un fichier non si grand (~ 30mo) analysant cela a pris environ 180 secondes pour effectuer une boucle ~ ~ (<>), contre environ 4 secondes en mode SLURP. Comme l'OP n'a pas défini l'utilisation de la mémoire sur le temps d'exécution en tant que critère, je ne pense pas que ma réponse mérite un '-' :(



27
votes

En tant que doublure:

perl -lne '/^--ERROR---.*Name="(.*?)" Age="(.*?)"/ && print "$1 $2"' file


3 commentaires

Quelles réponses similaires! Je ne me souviens jamais -l cependant, ++.


J'essaie d'utiliser cette technique et j'obtiens une ligne de sortie pour chaque match, mais il imprime uniquement des lignes vides. Si vous retirez le "$ 1 $ 2", il imprime toute la ligne correspondante. Une idée pourquoi je ne peux pas sembler imprimer les captures?


@Stevejorgensen Votre regex inclut-il des groupes de capture comme dans l'exemple donné?



7
votes

En tant que doublure, essayez: xxx

Ceci est beaucoup comme à l'aide de SED, mais avec la syntaxe Perl.


0 commentaires

2
votes

La question immédiate de "Comment utiliser Perl comme SED?" Il est préférable de répondre avec S2P, le convertisseur SED au PERL. Compte tenu de la ligne de commande, "SED $ Script", invoquer simplement "script S2P $" pour générer un script PERL (typiquement illisible) qui émule SED pour l'ensemble de commandes donné.


1 commentaires

S2P ne vient plus avec Perl, mais vous pouvez l'obtenir dans le module App :: S2P



31
votes
perl -pi -e 's/../../g' file

1 commentaires

Apparemment sur Windows 7, vous devez mettre "au lieu de".