OVH Cloud OVH Cloud

pattern de reconnaissance sur 2 lignes

10 réponses
Avatar
Jean-Philippe Caruana
Bonjour,

Je cherche à faire un script de lecture de fichier et de recherche de
pattern à cheval sur 2 ligne pour écrire un nouveau fichier contenant
les couples de lignes uniquement. Quelle peut être la meilleure méthode ?

--
jpc
http://www.enstimac.fr/~caruana/

10 réponses

Avatar
Antoun
Jean-Philippe Caruana wrote:

Bonjour,

Je cherche à faire un script de lecture de fichier et de recherche de
pattern à cheval sur 2 ligne pour écrire un nouveau fichier contenant
les couples de lignes uniquement. Quelle peut être la meilleure méthode ?



si ta seule spec est de coupler les lignes, le plus simple est encore de
lire ligne par ligne, par ex.

while($couple = <>) {
$couple .= <> ;
...
}

Sinon, merci de préciser ta demande !

Avatar
Jean-Philippe Caruana

Jean-Philippe Caruana wrote:

Bonjour,

Je cherche à faire un script de lecture de fichier et de recherche de
pattern à cheval sur 2 ligne pour écrire un nouveau fichier contenant
les couples de lignes uniquement. Quelle peut être la meilleure méthode ?



si ta seule spec est de coupler les lignes, le plus simple est encore de
lire ligne par ligne, par ex.

while($couple = <>) {
$couple .= <> ;
...
}


euh, bof...

Sinon, merci de préciser ta demande !


ok. il y a-t-il un moyen plsu élégant que :

------------------------------
my $lignePrecedante;
my $ligneCourante;
while (<FILE>) {
$ligneCourante = $_;
if (($ligneCourante =~ m/titi/) and ($lignePrecedante =~ m/toto/)) {
print RESULT $lignePrecedante . $ligneCourante;
}
$lignePrecedante = $ligneCourante ;
}
------------------------------

ou bien est-il meilleur de faire avec

undef $/

ou bien

$/ = ''

--
jpc
http://www.enstimac.fr/~caruana/


Avatar
Paul Gaborit
À (at) Tue, 14 Dec 2004 13:14:38 +0100,
Jean-Philippe Caruana écrivait (wrote):
ok. il y a-t-il un moyen plsu élégant que :

------------------------------
my $lignePrecedante;
my $ligneCourante;
while (<FILE>) {
$ligneCourante = $_;
if (($ligneCourante =~ m/titi/) and ($lignePrecedante =~ m/toto/)) {
print RESULT $lignePrecedante . $ligneCourante;
}
$lignePrecedante = $ligneCourante ;
}
------------------------------


Si ça marche, pourquoi faire autrement ? Il y a peut-être plus
"élégant"... mais ça ne sert pas à grand chose. Pour être plus rapide :

my $prec;
while (<FILE>) {
my $ligne = $_;
if (defined $prec and $ligne =~ m/titi/) {
print RESULT $prec . $ligne;
}
$prec = ($ligne =~ m/toto/) ? $ligne : undef;
}

ou bien est-il meilleur de faire avec

undef $/

ou bien

$/ = ''


Ces dernières propositions ne sont pas les bonnes (cela reviendrait à charger
tout le fichier en mémoire ou à le traiter par paragraphe).

Par contre, il faut que tu précises ton problème. Quand veux-tu afficher deux
lignes consécutives de ton fichier ?

- Quand la première est matchée par regexp1 et la seconde par regexp2 ?
(c'est le code que tu as fourni.)

- Quand les deux lignes considérées comme un seul texte sont matchée
par une regexp (qui peut parfois être à cheval sur les deux lignes) ?

Par ailleurs, est-il possible que trois lignes consécutives répondent aux
critères? En plus clair, si on rencontre :

ligne 1001: titi
ligne 1002: titi toto
ligne 1003: toto

doit-on afficher la ligne 1002 deux fois ou non ? (ton code affiche deux fois
cette ligne.)

PS: je me permets de te tutoyer car je crois qu'on s'est déjà rencontré dans
une autre vie ;-)

--
Paul Gaborit - <http://www.enstimac.fr/~gaborit/>
Perl en français - <http://www.enstimac.fr/Perl/>

Avatar
Xavier
Bonjour,

Je cherche à faire un script de lecture de fichier et de recherche de
pattern à cheval sur 2 ligne pour écrire un nouveau fichier contenant
les couples de lignes uniquement. Quelle peut être la meilleure méthode ?

On peut lire par paragraphe :

-000 sur la ligne de commande de perl ou $/="" dans le BEGIN;

ensuite, les expressions s'écrivent:
#!/usr/bin/perl -000 -w
while(<>) {
print "OKn" if/mon-expression/s;
}

Le 's' en fin d'expression signifie que le paragraphe ($_) est vu comme
une seule ligne. Tu peux aussi utiliser /m mais tu devra spécifier la
position de n dans ton expression:
print "OKn" if/ligne1nligne2/

@+
Xavier

Avatar
Jean-Philippe Caruana
ok. il y a-t-il un moyen plus élégant que :
my $lignePrecedante;
my $ligneCourante;
if (($ligneCourante =~ m/titi/) and ($lignePrecedante =~ m/toto/)) { ... }


Si ça marche, pourquoi faire autrement ? Il y a peut-être plus
"élégant"... mais ça ne sert pas à grand chose.


ok. j'aime assez le concept de "si ca marhce bien comme ca, touche pas !"

(en fait je postais pour qqun d'autre)
cette solution fontionne très bien pour moi, je ne pense pas entrer dans
des cas comme cités + bas (le format de fichier en entrée est plutot du
genre "figé dans le marbre"), donc je la garde comme elle est.

je recherche souvent l'élégance ET l'efficacité. Pour moi, élégance
signifie simplicité des concepts et propreté de la méthode. J'estime par
exemple que mettre tout un fichier en mémoire n'est pas propre, mais
selon les cas ca peut servir (? pas rencontré en tout cas, je contourne
tjs cette solution). C'est le point de vue du programmeur qui pense
revenir peut être un jour sur un script ou un autre.
Efficace = que ca marche, et le + rapidement possible. C'est le point de
vue du client.

ou bien est-il meilleur de faire avec
undef $/
$/ = ''
Ces dernières propositions ne sont pas les bonnes (cela reviendrait à charger

tout le fichier en mémoire ou à le traiter par paragraphe).


je sais bien, et c'est bien pour cette raison que je ne l'utilise pas. ;-p

en fait, je l'ai testé pour voir (quand meme !), mais à partir d'une
taille relativement faible du ficher, le temps de traitement s'allonge
beaucoup plus qu'avec la 1ère méthode. Je voulais d'autres avis à ce
sujet. Merci donc de me confirmer dans mon choix.


PS: je me permets de te tutoyer car je crois qu'on s'est déjà rencontré dans
une autre vie ;-)


eh oui ! le temps passe vite... ;-)

Merci pour ces réponses et ces pistes de réflexion. Je les garde dans un
coin au cas ou (en fait, je ne me pose pas svt la question autant à fond
que Paul G., alors ca sert tjs de voir jusqu'ou on peut creuser)

--
jpc
http://www.enstimac.fr/~caruana/


Avatar
Jean-Philippe Caruana
Par contre, il faut que tu précises ton problème. Quand veux-tu afficher deux
lignes consécutives de ton fichier ?

- Quand la première est matchée par regexp1 et la seconde par regexp2 ?
(c'est le code que tu as fourni.)


c'est tout a fait mon cas

- Quand les deux lignes considérées comme un seul texte sont matchée
par une regexp (qui peut parfois être à cheval sur les deux lignes) ?


dans ce cas, obligé de passer par les modificateurs */m* ou */s*
(perldoc perlfaq4 je crois), non ?
quelle est la meilleure solution dans ce cas ? Quand j'ai eu le
problème, je pensais qu'il s'agissait de *ce* cas, mais en fait il
s'agissais du 1er (résolu facilement donc). Mais du coup, mon post porte
sur cette question. Dans ce cas, doit-on charger le fichier (ou un
paragraphe) en mémoire ?

Par ailleurs, est-il possible que trois lignes consécutives répondent aux
critères? En plus clair, si on rencontre :

ligne 1001: titi
ligne 1002: titi toto
ligne 1003: toto

doit-on afficher la ligne 1002 deux fois ou non ? (ton code affiche deux fois
cette ligne.)


normalement non, mais je n'y avais pas pensé (cf la fin de mon post
précédant). Le problème dans ce cas est de déterminer "le bon cas" :
doit-on afficher la ligne 1002 deux fois ou non ?
doit-on afficher les lignes 1001 et 1002 ou 1002 et 1003 ?

Comme le problème ne se pose pas dans mon cas, impossible d'aller plus
loin ici.

--
jpc
http://www.enstimac.fr/~caruana/

Avatar
Paul Gaborit
À (at) Wed, 15 Dec 2004 17:30:03 +0100,
Jean-Philippe Caruana écrivait (wrote):
Efficace = que ca marche, et le + rapidement possible. C'est le point de vue
du client.


Le problème de cette formulation est de savoir à quoi se rapporte "le +
rapidement possible"... Est-ce au temps de développement ou au temps
d'exécution ?

Sinon, il ne faut pas oublier les trois vertues du programmeur selon Larry
Wall...

--
Paul Gaborit - <http://www.enstimac.fr/~gaborit/>
Perl en français - <http://www.enstimac.fr/Perl/>

Avatar
Jean-Philippe Caruana
À (at) Wed, 15 Dec 2004 17:30:03 +0100,
Jean-Philippe Caruana écrivait (wrote):

Efficace = que ca marche, et le + rapidement possible. C'est le point de vue
du client.



Le problème de cette formulation est de savoir à quoi se rapporte "le +
rapidement possible"... Est-ce au temps de développement ou au temps
d'exécution ?


pour moi qui travaille désormais pour une entreprise privée, ca serait
plutot par rapport au temps d'execution.

Sinon, il ne faut pas oublier les trois vertues du programmeur selon Larry
Wall...


j'ai un trou là...

--
jpc
http://www.enstimac.fr/~caruana/


Avatar
Paul Gaborit
À (at) Thu, 16 Dec 2004 12:38:21 +0100,
Jean-Philippe Caruana écrivait (wrote):
Le problème de cette formulation est de savoir à quoi se rapporte "le +
rapidement possible"... Est-ce au temps de développement ou au temps
d'exécution ?


pour moi qui travaille désormais pour une entreprise privée, ca serait plutot
par rapport au temps d'execution.


Tiens, dans un contexte privé, j'aurais parié sur le contraire... En fait le
chef pense que ça se rapporte au temps de développement alors que le client
préfère que ça se rapporte au temps d'exécution.

Sinon, il ne faut pas oublier les trois vertues du programmeur selon Larry
Wall...


j'ai un trou là...


La paresse, l'impatience et l'orgueil. Pour en savoir plus :

<http://c2.com/cgi/wiki?LazinessImpatienceHubris>

--
Paul Gaborit - <http://www.enstimac.fr/~gaborit/>
Perl en français - <http://www.enstimac.fr/Perl/>


Avatar
Jean-Philippe Caruana
Le problème de cette formulation est de savoir à quoi se rapporte "le +
rapidement possible"... Est-ce au temps de développement ou au temps
d'exécution ?


pour moi qui travaille désormais pour une entreprise privée, ca serait plutot
par rapport au temps d'execution.


Tiens, dans un contexte privé, j'aurais parié sur le contraire... En fait le
chef pense que ça se rapporte au temps de développement alors que le client
préfère que ça se rapporte au temps d'exécution.


ca doit dépendre des boites alors.
c'est surtout lié à la "force" de la MOA : si ils sont super exigents,
alors on se rapportera au tps d'execution. Dans le cas contraire, en cas
de fortes contraintes de temps de dev, j'imagine que ce sera l'opposé...
(J'espère travailler "dans le bon sens" si je puis dire. En tout cas,
j'essaye.)

Sinon, il ne faut pas oublier les trois vertues du programmeur selon Larry
Wall...
La paresse, l'impatience et l'orgueil.




en effet ;-) c'est tout a fait exact !
Tout ceci est également rappelé dans l'intro du bouquin sur _sed & awk_
chez o'reilly, mais avec une élégance moindre je trouve :

<< *Je préfère raffiner une solution plutôt que de répéter, tel un
robot, une série de frappes au clavier. En plus, quand la tâche est
accomplie, je me trouve astucieux : j'ai le sentiment d'être un magicien
et je me suis épargné une tâche ennuyeuse.*
_Awk, fils de sed et de grep, descendant d'ed._ >>

allez, bonne journée à tous.

--
jpc
http://www.enstimac.fr/~caruana/