J'essaye d'ouvrir un fichier .html comme une grande et longue chaîne. Voici ce que j'ai:
open(FILE, 'index.html') or die "Can't read file 'filename' [$!]\n";
$document = <FILE>;
close (FILE);
print $document;
ce qui se traduit par:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN
Cependant, je veux que le résultat ressemble à:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
De cette façon, je peux rechercher plus facilement l'ensemble du document.
Réponses:
Ajouter:
avant de lire le descripteur de fichier. Voir Comment puis-je lire un fichier entier en une seule fois? , ou
Voir Variables liées aux descripteurs de fichiers dans
perldoc perlvar
etperldoc -f local
.Incidemment, si vous pouvez mettre votre script sur le serveur, vous pouvez avoir tous les modules que vous souhaitez. Voir Comment conserver mon propre répertoire module / bibliothèque? .
De plus, Chemin :: Class :: File vous permet de Slurp et crachez .
Chemin :: minuscule donne encore plus des méthodes pratiques telles que
slurp
,slurp_raw
,slurp_utf8
ainsi que leursspew
homologues.la source
$/
, vous devriez probablement ajouter des liens pour plus d'informations.local
et nonmy
.Je le ferais comme ceci:
Notez l'utilisation de la version à trois arguments de open. C'est beaucoup plus sûr que les anciennes versions à deux (ou un) arguments. Notez également l'utilisation d'un descripteur de fichier lexical. Les descripteurs de fichiers lexicaux sont plus agréables que les anciennes variantes bareword, pour de nombreuses raisons. Nous profitons de l'un d'entre eux ici: ils se ferment lorsqu'ils sortent du champ de vision.
la source
Avec File :: Slurp :
Oui, même vous pouvez utiliser CPAN .
la source
Can't locate File/Slurp.pm in @INC (@INC contains: /usr/lib/perl5/5.8/msys
:(Tous les messages sont légèrement non idiomatiques. L'idiome est:
Généralement, il n'est pas nécessaire de définir $ / sur
undef
.la source
local $foo = undef
est juste la méthode suggérée par Perl Best Practice (PBP). Si nous publions des extraits de code, je pense que faire de notre mieux pour le rendre clair serait une bonne chose.De perlfaq5: Comment puis-je lire un fichier entier en une seule fois? :
Vous pouvez utiliser le module File :: Slurp pour le faire en une seule étape.
L'approche Perl habituelle pour traiter toutes les lignes d'un fichier est de le faire une ligne à la fois:
C'est beaucoup plus efficace que de lire l'intégralité du fichier en mémoire sous la forme d'un tableau de lignes, puis de le traiter un élément à la fois, ce qui est souvent - sinon presque toujours - la mauvaise approche. Chaque fois que vous voyez quelqu'un faire ceci:
vous devriez réfléchir longuement aux raisons pour lesquelles vous avez besoin de tout chargé en même temps. Ce n'est tout simplement pas une solution évolutive. Vous pouvez également trouver plus amusant d'utiliser le module standard Tie :: File, ou les liaisons $ DB_RECNO du module DB_File, qui vous permettent de lier un tableau à un fichier afin que l'accès à un élément du tableau accède réellement à la ligne correspondante dans le fichier. .
Vous pouvez lire l'intégralité du contenu du descripteur de fichier dans un scalaire.
Cela annule temporairement votre séparateur d'enregistrement et ferme automatiquement le fichier à la sortie du bloc. Si le fichier est déjà ouvert, utilisez simplement ceci:
Pour les fichiers ordinaires, vous pouvez également utiliser la fonction de lecture.
Le troisième argument teste la taille en octets des données sur le descripteur de fichier INPUT et lit autant d'octets dans le tampon $ var.
la source
Un moyen simple est:
Une autre façon est de changer le séparateur d'enregistrement d'entrée "$ /". Vous pouvez le faire localement dans un bloc nu pour éviter de changer le séparateur d'enregistrements global.
la source
{local $/; open(my $f, '<', 'filename'); $d = <$f>;}
open
ou l'appel implicitementclose
.my $d = do{ local $/; open(my $f, '<', 'filename') or die $!; my $tmp = <$f>; close $f or die $!; $tmp}
. (Cela a toujours le problème qu'il ne spécifie pas l'encodage d'entrée.)use autodie
, l'amélioration majeure que je voulais montrer était le descripteur de fichier lexical et les 3 arg open. Y a-t-il une raison pour laquelle vous faitesdo
cela? pourquoi ne pas simplement vider le fichier dans une variable déclarée avant le bloc?Soit défini
$/
surundef
(voir la réponse de jrockway), soit concaténez simplement toutes les lignes du fichier:Il est recommandé d'utiliser des scalaires pour les descripteurs de fichiers sur toute version de Perl qui le prend en charge.
la source
Un autre moyen possible:
la source
Vous n'obtenez la première ligne de l'opérateur diamant que
<FILE>
parce que vous l'évaluez dans un contexte scalaire:Dans un contexte liste / tableau, l'opérateur losange retournera toutes les lignes du fichier.
la source
<=>
et le<>
est l'opérateur diamant.Je le ferais de la manière la plus simple, pour que tout le monde puisse comprendre ce qui se passe, même s'il existe des moyens plus intelligents:
la source
<f>
- renvoie un tableau de lignes de notre fichier (si$/
a la valeur par défaut"\n"
) etjoin ''
collera ensuite ce tableau dans.la source
Ceci est plus une suggestion sur la façon NE PAS le faire. J'ai juste eu du mal à trouver un bogue dans une assez grosse application Perl. La plupart des modules avaient leurs propres fichiers de configuration. Pour lire les fichiers de configuration dans leur ensemble, j'ai trouvé cette seule ligne de Perl quelque part sur Internet:
Il réaffecte le séparateur de ligne comme expliqué précédemment. Mais il réaffecte également le STDIN.
Cela a eu au moins un effet secondaire qui m'a coûté des heures à trouver: il ne ferme pas correctement le descripteur de fichier implicite (car il n'appelle pas
close
du tout).Par exemple, en faisant cela:
résulte en:
La chose étrange est que le compteur de ligne
$.
est augmenté de un pour chaque fichier. Il n'est pas réinitialisé et ne contient pas le nombre de lignes. Et il n'est pas remis à zéro lors de l'ouverture d'un autre fichier jusqu'à ce qu'au moins une ligne soit lue. Dans mon cas, je faisais quelque chose comme ça:En raison de ce problème, la condition était fausse car le compteur de ligne n'a pas été réinitialisé correctement. Je ne sais pas s'il s'agit d'un bug ou simplement d'un code erroné ... Appelant également
close;
oderclose STDIN;
n'aide pas non plus.J'ai remplacé ce code illisible en utilisant open, string concatenation and close. Cependant, la solution publiée par Brad Gilbert fonctionne également puisqu'elle utilise à la place un descripteur de fichier explicite.
Les trois lignes du début peuvent être remplacées par:
qui ferme correctement le descripteur de fichier.
la source
Utilisation
avant
$document = <FILE>;
.$/
est le séparateur d'enregistrement d'entrée , qui est une nouvelle ligne par défaut. En le redéfinissant pourundef
, vous dites qu'il n'y a pas de séparateur de champ. C'est ce qu'on appelle le mode "slurp".D'autres solutions comme
undef $/
etlocal $/
(mais pasmy $/
) redéclarent $ / et produisent ainsi le même effet.la source
Vous pouvez simplement créer une sous-routine:
la source
Je ne sais pas si c'est une bonne pratique, mais j'avais l'habitude d'utiliser ceci:
la source
Ce sont toutes de bonnes réponses. MAIS si vous vous sentez paresseux et que le fichier n'est pas si gros et que la sécurité n'est pas un problème (vous savez que vous n'avez pas de nom de fichier corrompu), alors vous pouvez débourser:
la source
Vous pouvez utiliser cat sous Linux:
la source