OVH Cloud OVH Cloud

Html & split

61 réponses
Avatar
ptilou
Bonsoir,

J'ai un fichier de 50 Mo, je souhaiterais le d=E9couper =E0 chaque fois
qu'il y a la balise <HTML> en un "fichier fille"
Voila se que j'ai fais et marche pas :
#!/usr/local/bin/perl -wn
BEGIN {
$file =3D "$0";
$/ =3D \<HTML>;
$n =3D 1;
}
unless( $n++ % \<HTML> ) { close F;
open F, "> $file.csv"
or die "Impossible de cr=E9er $file.csv: $!";
$file++;
}
print F;

L'erreur : $ perl -w cut-perl partie00
readline() on unopened filehandle HTML at cut-perl line 4.
Use of uninitialized value in <HANDLE> at cut-perl line 1.
readline() on unopened filehandle HTML at cut-perl line 7.
print() on unopened filehandle F at cut-perl line 12.
Use of uninitialized value in <HANDLE> at cut-perl line 12, <> chunk 1.

Mer=E7i

Ptilou

10 réponses

1 2 3 4 5
Avatar
ptilou
Bonjour,

J'ai un fichier de 50 Mo, je souhaiterais le découper à chaque fois
qu'il y a la balise <HTML> en un "fichier fille"


Je m'en tiens à ton cahier des charges, et pas à ton code.

#!/usr/bin/perl
use strict;
use warnings;

usage($0) unless (@ARGV);

foreach my $file (@ARGV) {
open(my $fh, "<", $file) || die "Erreur lors de l'ouverture de $file :
$!";
my $content = undef;
{ local $/; $content = <$fh>; } # slurp !
if ($content =~ m{<HTML>.*</HTML>}is) {
open(my $out, ">", "$file.out") ||
die "Erreur lors de l'ouverture de $file.out :
$!";
print $out $1;
close($out) ||
print STDERR "erreur lors de la fermeture de
$file.outn";
}
close($fh) || print STDERR "Erreur lors de la fermeture de $file :
$!n";
}

sub usage {
my $progname = shift;
print STDERR "USAGE : $progname { fichiers à examiner }n";
exit(1);
}


J'ai pas compris ! Et se qui me rassure mon PC aussi ! Il dit :
Use of uninitialized value in print at ./decoupe-perl line 16, <$fh>
line 1.

Je veux bien un tableau mais le fichier fait 800 000 lignes, va pas y
avoir de PB ? (@ARGV)
J'ai toujour pas compris pourquoi sed s'arrete à 389136 lignes ?
Je vois pas ou sa découpe ?
Mais , il faut utiliser split ou pas ?

Merçi

Ptilou


Avatar
Stephane Zuckerman
<snip>
J'ai pas compris ! Et se qui me rassure mon PC aussi ! Il dit :
Use of uninitialized value in print at ./decoupe-perl line 16, <$fh>
line 1.


Quelle est la ligne de commande utilisée ?
J'ai testé deux cas :

$ perl html.pl toto.html
(il me sort bien un toto.html.out)
et
$ perl html.pl toto.html titi.html
(et j'ai bien toto.html.out et titi.html.out)

Je veux bien un tableau mais le fichier fait 800 000 lignes, va pas y
avoir de PB ? (@ARGV)


@ARGV est la liste des arguments donnés au script.
Par exemple,
$ perl html.pl toto.html
donne un tableau @ARGV contenant "toto.html".
$ perl html.pl toto.html titi.html
donne un @ARGV contenant ["toto.html", "titi.html"].

Globalement, pour chaque fichier donné en argument, j'y insère le contenu
dans une variable temporaire ($content), je regarde si elle contient la
regexp "<HTML>.*</HTML>", et si oui, je crée un fichier $file.out ($file
étant le nom du fichier en cours de traitement) et j'écris le contenu de
$content dedans.

J'ai toujour pas compris pourquoi sed s'arrete à 389136 lignes ?
J'en sais rien.


Je vois pas ou sa découpe ?
Ca se trouve, ce le script que j'ai pondu ne correspond pas vraiment à ce

que tu veux. Explique mieux comment est fait un de tes fichiers.

S'agit-il d'un fichier contenant plusieurs couples de balises
<HTML></HTML> ?
Si oui, mon script ne te servira pas vraiment (mais c'est un bon début).

Mais , il faut utiliser split ou pas ?
Tout dépend de ce que tu veux faire avec. Mais ta demande est trop vague,

il faut que tu précises. Telle que je l'ai comprise, le split est inutile
ici.

--
"Je deteste les ordinateurs : ils font toujours ce que je dis, jamais ce
que je veux !"
"The obvious mathematical breakthrough would be development of an easy
way to factor large prime numbers." (Bill Gates, The Road Ahead)

Avatar
damien guerin
Essai mon code... il fonctionne... Apres tu peux l'améliorer :

open (IN, "< file.html");
open (OUT, ">out.tmp");
$cpt=0;
while ($line = <IN>) {
if ($line =~ /</HTML>/) {
$cpt++;
print OUT $line;
close OUT;
rename "out.tmp", $cpt.".html";
open (OUT, ">out.tmp");
} else {
print OUT $line;
}

}
close OUT;

Il transforme le fichier file.html :

<HTML>
page 1
</HTML>
<HTML>
page 2
</HTML>
<HTML>
page 3
</HTML>

en 3 fichiers 1.html, 2.html et 3.html contenant :
<HTML>
page 1
</HTML>

et

<HTML>
page 2
</HTML>

et

<HTML>
page 3
</HTML>

voilàààààà !!
Avatar
Stephane Zuckerman
open (IN, "< file.html");
open (OUT, ">out.tmp");
$cpt=0;
while ($line = <IN>) {
if ($line =~ /</HTML>/) {
$cpt++;
print OUT $line;
close OUT;
rename "out.tmp", $cpt.".html";
open (OUT, ">out.tmp");
} else {
print OUT $line;
}

}
close OUT;


Oui, ça m'a l'air bien comme script, ça. :-)
--
"Je deteste les ordinateurs : ils font toujours ce que je dis, jamais ce
que je veux !"
"The obvious mathematical breakthrough would be development of an easy
way to factor large prime numbers." (Bill Gates, The Road Ahead)

Avatar
Laurent Wacrenier
damien guerin écrit:
Essai mon code... il fonctionne...


sauf que les trucs avant ou après </HTML> sur la ligne sont perdus.

Avatar
Stephane Zuckerman
sauf que les trucs avant ou après </HTML> sur la ligne sont perdus.


Comment ça ? Il ne fait que tester la "fin de fichier" en regardant si la
ligne courante contient "</HTML>". Il ferme donc le fichier fils courant,
et en ouvre un autre. Je ne vois pas comment on perd des informations ...

--
"Je deteste les ordinateurs : ils font toujours ce que je dis, jamais ce
que je veux !"
"The obvious mathematical breakthrough would be development of an easy
way to factor large prime numbers." (Bill Gates, The Road Ahead)

Avatar
ptilou
Bonjour, et merci,

Mais ci sa ne t'ennuis pas, j'insiste :

damien guerin wrote:
Essai mon code... il fonctionne... Apres tu peux l'améliorer :

open (IN, "< file.html"); si je remplace par :open (IN, "< $_[$[]") or d ie ;


Pourquoi la grammaire est si compliquer pour passer le nom en variable
? je peux pas le remplacer par $z a la place de "< $_[$[]" ?

open (OUT, ">out.tmp");

$cpt=0; # Pourquoi 0 et pas1 ?

while ($line = <IN>) {
if ($line =~ /</HTML>/) {
$cpt++;
print OUT $line;

close OUT; #sa ferme quoi ?

rename "out.tmp", $cpt.".html";
open (OUT, ">out.tmp");
} else {
print OUT $line; # sa imprime le comptenu, mais je croyais qu 'il été fermer le fichier ?

}

}
close OUT;

Il transforme le fichier file.html :



Ca marche nickel ...
Mais maintenant je voudrais l'améliorer pour qu'il supporte du
binaire, je crois que c'est la commande unpack -h puis pack à la
sauvegarde ?


Encore merci de ta patience !

Ptilou

Avatar
Laurent Wacrenier
Stephane Zuckerman écrit:
sauf que les trucs avant ou après </HTML> sur la ligne sont perdus.


Comment ça ? Il ne fait que tester la "fin de fichier" en regardant si la
ligne courante contient "</HTML>". Il ferme donc le fichier fils courant,
et en ouvre un autre. Je ne vois pas comment on perd des informations ...


Et si la ligne est

pincemi</HTML>pincemoi

qu'est ce qu'il reste ?


Avatar
Nicolas Le Scouarnec
sauf que les trucs avant ou après </HTML> sur la ligne sont perdus.
Comment ça ? Il ne fait que tester la "fin de fichier" en regardant si la

ligne courante contient "</HTML>". Il ferme donc le fichier fils courant,
et en ouvre un autre. Je ne vois pas comment on perd des informations ...


Si on a un

aaaa</HTML>bbbb

Le bbb devrait aller dans le fichier suivant, il ira dans le fichier
courant ici. Ceci dit, si les </HTML> sont seul sur leur ligne, ca ne
pose pas de problemes.


--
Nicolas Le Scouarnec


Avatar
Stephane Zuckerman
Stephane Zuckerman écrit:
sauf que les trucs avant ou après </HTML> sur la ligne sont perdus.


Comment ça ? Il ne fait que tester la "fin de fichier" en regardant si la
ligne courante contient "</HTML>". Il ferme donc le fichier fils courant,
et en ouvre un autre. Je ne vois pas comment on perd des informations ...


Et si la ligne est

pincemi</HTML>pincemoi

qu'est ce qu'il reste ?


OK. :-)
Cela dit, pour des histoires de "lisibilité" il me semblerait plus
"logique" que les balises <HTML></HTML> soient sur une ligne à part...
Maintenant en effet, le script précédent ne prend pas le cas général en
compte...

--
"Je deteste les ordinateurs : ils font toujours ce que je dis, jamais ce
que je veux !"
"The obvious mathematical breakthrough would be development of an easy
way to factor large prime numbers." (Bill Gates, The Road Ahead)



1 2 3 4 5