Estoy intentando abrir un archivo .html como una cadena larga y grande. Esto es lo que tengo:
open(FILE, 'index.html') or die "Can't read file 'filename' [$!]\n";
$document = <FILE>;
close (FILE);
print $document;
lo que resulta en:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN
Sin embargo, quiero que el resultado se vea así:
<!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 esta forma puedo buscar en todo el documento con mayor facilidad.
Respuestas:
Añadir:
antes de leer desde el identificador de archivo. Consulte ¿Cómo puedo leer un archivo completo de una vez? o
Consulte Variables relacionadas con identificadores de archivos en
perldoc perlvar
yperldoc -f local
.Por cierto, si puede poner su script en el servidor, puede tener todos los módulos que desee. Consulte ¿Cómo mantengo mi propio directorio de módulos / bibliotecas? .
Además, Path :: Class :: File te permite sorber y escupir .
Path :: Tiny da aún más métodos de conveniencia como
slurp
,slurp_raw
,slurp_utf8
así como susspew
homólogos.fuente
$/
, probablemente debería agregar enlaces para obtener más información.local
y nomy
.Lo haría así:
Tenga en cuenta el uso de la versión de tres argumentos de open. Es mucho más seguro que las versiones antiguas de dos (o uno) argumentos. También tenga en cuenta el uso de un identificador de archivo léxico. Los identificadores de archivos léxicos son más agradables que las antiguas variantes de palabras sin formato, por muchas razones. Estamos aprovechando uno de ellos aquí: cierran cuando se salen de alcance.
fuente
Con Archivo :: Slurp :
Sí, incluso tú puedes usar CPAN .
fuente
Can't locate File/Slurp.pm in @INC (@INC contains: /usr/lib/perl5/5.8/msys
:(Todas las publicaciones son un poco no idiomáticas. El modismo es:
En general, no es necesario establecer $ / to
undef
.fuente
local $foo = undef
es solo el método sugerido por Perl Best Practice (PBP). Si publicamos fragmentos de código, creo que hacer todo lo posible para dejarlo claro sería algo bueno.De perlfaq5: ¿Cómo puedo leer un archivo completo de una vez? :
Puede usar el módulo File :: Slurp para hacerlo en un solo paso.
El enfoque habitual de Perl para procesar todas las líneas de un archivo es hacerlo una línea a la vez:
Esto es tremendamente más eficiente que leer todo el archivo en la memoria como una matriz de líneas y luego procesarlo un elemento a la vez, lo que a menudo, si no casi siempre, es el enfoque incorrecto. Siempre que veas a alguien hacer esto:
debe pensar detenidamente por qué necesita todo cargado a la vez. Simplemente no es una solución escalable. También puede que le resulte más divertido utilizar el módulo estándar Tie :: File, o los enlaces $ DB_RECNO del módulo DB_File, que le permiten vincular una matriz a un archivo para que, al acceder a un elemento, la matriz acceda a la línea correspondiente del archivo. .
Puede leer todo el contenido del identificador de archivo en un escalar.
Eso anula temporalmente su separador de registros y cerrará automáticamente el archivo al salir del bloque. Si el archivo ya está abierto, simplemente use esto:
Para archivos normales, también puede utilizar la función de lectura.
El tercer argumento prueba el tamaño de bytes de los datos en el identificador de archivo INPUT y lee esa cantidad de bytes en el búfer $ var.
fuente
Una forma sencilla es:
Otra forma es cambiar el separador de registros de entrada "$ /". Puede hacerlo localmente en un bloque simple para evitar cambiar el separador de registros global.
fuente
{local $/; open(my $f, '<', 'filename'); $d = <$f>;}
open
o el llamado implícitamenteclose
.my $d = do{ local $/; open(my $f, '<', 'filename') or die $!; my $tmp = <$f>; close $f or die $!; $tmp}
. (Eso todavía tiene el problema de que no especifica la codificación de entrada.)use autodie
, la principal mejora que quise mostrar fue el identificador de archivo léxico y el 3 arg abierto. ¿Hay alguna razón por la que estásdo
haciendo esto? ¿Por qué no volcar el archivo en una variable declarada antes del bloque?Puede configurarlo
$/
enundef
(ver la respuesta de jrockway) o simplemente concatenar todas las líneas del archivo:Se recomienda utilizar escalares para identificadores de archivos en cualquier versión de Perl que lo admita.
fuente
Otra forma posible:
fuente
Solo obtiene la primera línea del operador de diamante
<FILE>
porque la está evaluando en un contexto escalar:En el contexto de lista / matriz, el operador de diamante devolverá todas las líneas del archivo.
fuente
<=>
y el<>
es el operador de diamante.Lo haría de la manera más simple, para que cualquiera pueda entender lo que sucede, incluso si hay formas más inteligentes:
fuente
<f>
- devuelve una matriz de líneas de nuestro archivo (si$/
tiene el valor predeterminado"\n"
) y luegojoin ''
pegará esta matriz.fuente
Esto es más una sugerencia sobre cómo NO hacerlo. Lo he pasado mal para encontrar un error en una aplicación Perl bastante grande. La mayoría de los módulos tenían sus propios archivos de configuración. Para leer los archivos de configuración en su conjunto, encontré esta única línea de Perl en algún lugar de Internet:
Reasigna el separador de línea como se explicó anteriormente. Pero también reasigna el STDIN.
Esto tuvo al menos un efecto secundario que me costó horas encontrarlo: no cierra correctamente el identificador de archivo implícito (ya que no llama
close
en absoluto).Por ejemplo, haciendo eso:
resulta en:
Lo extraño es que el contador de líneas
$.
aumenta en uno para cada archivo. No se restablece y no contiene el número de líneas. Y no se restablece a cero al abrir otro archivo hasta que se lee al menos una línea. En mi caso, estaba haciendo algo como esto:Debido a este problema, la condición era falsa porque el contador de línea no se restableció correctamente. No sé si esto es un error o simplemente un código incorrecto ... Además, llamar a
close;
oderclose STDIN;
no ayuda.Reemplacé este código ilegible usando abrir, concatenación de cadenas y cerrar. Sin embargo, la solución publicada por Brad Gilbert también funciona, ya que utiliza un identificador de archivo explícito.
Las tres líneas al principio se pueden reemplazar por:
que cierra correctamente el identificador del archivo.
fuente
Utilizar
antes
$document = <FILE>;
.$/
es el separador de registros de entrada , que es una nueva línea por defecto. Al redefinirlo aundef
, está diciendo que no hay un separador de campo. Esto se llama modo "sorber".Otras soluciones como
undef $/
ylocal $/
(pero nomy $/
) redeclaran $ / y por lo tanto producen el mismo efecto.fuente
Simplemente podría crear una subrutina:
fuente
No sé si es una buena práctica, pero solía usar esto:
fuente
Todas estas son buenas respuestas. PERO si se siente perezoso y el archivo no es tan grande, y la seguridad no es un problema (sabe que no tiene un nombre de archivo contaminado), entonces puede pagar:
fuente
Puedes usar cat en Linux:
fuente