Une approche en force brute implique la configuration de votre propre pipeline en pointant STDOUT
à tail
. Cela vous permet d'imprimer toutes les erreurs, puis c'est à tail
de se soucier de ne laisser que le dernier.
Vous n'avez pas spécifié, je suppose donc une ligne de configuration juridique est de la forme
Name = some value
Matching qui est simple:
^
(à partir du début de la ligne)
\w+
(un ou plusieurs «caractères de mot»)
\s+
(suivi d'un espace obligatoire)
=
(suivi d'un signe égal)
\s+
(plus les espaces obligatoires)
.+
(une valeur obligatoire)
$
(finition à la fin de la ligne)
collant ensemble, nous obtenons
#! /usr/bin/perl
use warnings;
use strict;
# for demo only
*ARGV = *DATA;
my $pid = open STDOUT, "|-", "tail", "-1" or die "$0: open: $!";
while (<>) {
print unless /^ \w+ \s+ = \s+ .+ $/x;
}
close STDOUT or warn "$0: close: $!";
__DATA__
This = assignment is ok
But := not this
And == definitely not this
Sortie:
$ ./lasterr
And == definitely not this
Avec des expressions régulières, quand vous voulez la dernière occurrence d'un motif, placez ^.*
à l'avant de votre modèle.Par exemple, pour remplacer le dernier X dans l'entrée avec Y, utilisez
$ echo XABCXXXQQQXX | perl -pe 's/^(.*)X/$1Y/'
XABCXXXQQQXY
Notez que le ^
est redondant, car regular-expression quantifiers sont avides, mais j'aime l'avoir là pour l'accent.
En appliquant cette technique à votre problème, vous pouvez rechercher la dernière ligne dans votre fichier de configuration qui contient une erreur dans le programme suivant:
#! /usr/bin/perl
use warnings;
use strict;
local $_ = do { local $/; scalar <DATA> };
if (/\A.* ^(?! \w+ \s+ = \s+ [^\r\n]+ $) (.+?)$/smx) {
print $1, "\n";
}
__DATA__
This = assignment is ok
But := not this
And == definitely not this
La syntaxe de l'expression régulière est un peu différent car $_
contient plusieurs lignes, mais le principe est le même. \A
est similaire à ^
, mais il correspond à seulement au début de la chaîne à rechercher. Avec les /m
switch (“multi-line”), ^
correspond aux limites de ligne logique.
Jusqu'à ce point, nous savons que le modèle
/\A.*^.../
correspond à la dernière ligne qui ressemble à quelque chose. Le negative look-ahead assertion(?!...)
recherche une ligne qui est pas une ligne de configuration légale. En règle générale, .
correspond à n'importe quel caractère sauf le saut de ligne, mais le /s
switch (“single line”) lève cette restriction. La spécification de [^\r\n]+
, c'est-à-dire un ou plusieurs caractères qui ne sont ni retour chariot, ni saut de ligne, ne permet pas à la correspondance de déborder dans la ligne suivante.
Look-around assertions ne pas capturer, donc nous attrapons la ligne fautive avec (.+?)$
. La raison pour laquelle il est sûr d'utiliser .
dans ce contexte est que nous savons que la ligne en cours est mauvaise et que non-greedy quantifier +?
cesse de correspondre dès que possible, ce qui dans ce cas est la fin de la ligne logique actuelle.
Toutes ces expressions régulières utilisent le /x
switch (“extended mode”) pour autoriser des espaces supplémentaires: l'objectif est d'améliorer la lisibilité.
Qu'avez-vous écrit jusqu'à présent? – msw
manière la plus simple, utilisez la queue. par exemple. perl my_perl_script_that_prints_out_errors.pl | tail -1 – zen