• Publicidad

Recorrer rangos de líneas de archivo en un arreglo

¿Apenas comienzas con Perl? En este foro podrás encontrar y hacer preguntas básicas de Perl con respuestas aptas a tu nivel.

Recorrer rangos de líneas de archivo en un arreglo

Notapor diana » 2005-07-09 20:03 @877

Hola.

Espero que pueda alguien ayudarme, estoy haciendo mi tesis y estoy aprendiendo Perl.

Lo que intento hacer es: tengo un archivo html que tiene URL en cierto número de línea del archivo.

Lo que estoy haciendo es crear un arreglo que guarda el número de líneas que tienen cierto patrón en el archivo, por ejemplo, en que en las líneas 2, 10, 68... tengo las cadenas http, hice un arreglo que guarda esas líneas, y quiero que me tome de dos en dos ese arreglo creado, para eso creo dos for anidados; el primero recorre todos los elementos y el segundo inicia del segundo elemento en adelante. Se supone que así ya tengo los elementos de dos en dos.

Con esto lo que pretendo hacer es tomar los rangos de las líneas que quiero que se impriman en un archivo diferente.

Espero no haberlos confundido. De todas formas adjunto el código. Espero que puedan ayudarme a resolver el problema.

Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1. $num_param = 0;
  2. if   ( $ARGV[0] ) { $entrada   = $ARGV[0]; }
  3. else              { $num_param = 1; }
  4.  
  5. if   ( $ARGV[1] ) { $salida    = $ARGV[1]; }
  6. else              { $num_param = 1; }
  7.  
  8. if ( $num_param != 0 ) { print "faltan $num_param par metro(s)"; }
  9. else {
  10.     open( ENTRADA, "$entrada" )  || die "no se pudo abrir el archivo: $!\n";
  11.     open( SALIDA,  "+>$salida" ) || die "no se pudo abrir $salida: $!\n";
  12. }
  13.  
  14. LINE: while ( $linea = <ENTRADA> ) {
  15.     $cont = $.;
  16.  
  17.     #Creo tabla hash con el numero de linea y el texto de la linea correspondiente.
  18.     %asocia = ( $cont, $linea );
  19.     @line = $linea;
  20.     if ( $linea =~ /http:\/\/serpiente.dgsca.unam.mx\/jornada\/2000\/ene00\/000118\// ) {
  21.         my $c = $.;
  22.         @cuantas = $c;
  23.         $cuant   = @cuantas;
  24.     }
  25.  
  26.     #genero con este for el par de elementos del arreglo
  27.     for ( $g = 0; $g < $cuant; $g++ ) {
  28.         print SALIDA "uno ", $cuantas[$g] . "\n dos ", $cuantas[ $g++ ];    #obtengo 2,10
  29.                                        #hago un for que recorre uno por uno el rango obtenido en el for anterior
  30.         for ( my $h = $cuantas[$g]; $h < $cuantas[ $g++ ]; $h++ ) {    #trato de obtener 2,3,4,..,10
  31.                                        # foreach $j(keys %asocia) {
  32.             print SALIDA $asocia{$h};  #trato de mostrar las lineas 2 a la 10 del archivo.
  33.                                        # }
  34.         }
  35.     }
  36. }
  37. close(ENTRADA);
  38. close(SALIDA);
Coloreado en 0.003 segundos, usando GeSHi 1.0.8.4
diana
Perlero nuevo
Perlero nuevo
 
Mensajes: 8
Registrado: 2005-07-01 20:27 @894

Publicidad

Notapor kidd » 2005-07-10 08:51 @410

Hola, Diana:

Estoy hecho totalmente bolas con tu código. Quizá te podríamos ayudar más si nos pudieras mostrar el archivo del cual estás haciendo el análisis. En este caso sería el de ENTRADA.

Lo que entiendo es que quieres sacar todos los http:// que hay dentro del archivo y después escribirlos de dos en dos en el archivo SALIDA. No sé si haya entendido bien tu explicación.


SALUDOS
Uriel Lizama Perl programmer fundador de Perl en Español
Perl Programming Language
Avatar de Usuario
kidd
Creador de Perl en Español
Creador de Perl en Español
 
Mensajes: 1166
Registrado: 2003-10-15 16:52 @744
Ubicación: México

Re:for para recorrer arreglo

Notapor diana » 2005-07-11 13:17 @595

Hola, kidd.

Mira, yo tengo un archivo html en el que se juntaron varias páginas HTML.

Lo que pretendo hacer con el código es obtener todos las URL de ese archivo mediante una tabla hash que tiene el número de línea en el que esta el http (que es el patrón que busco en el if) y la línea.

Con esto yo lo que tengo son todos los números de línea en el que están los http, ya con esto lo que quiero hacer son dos for que me van a ayudar a obtener esos números de dos en dos.

Para esto tengo un arreglo que guarda todos los números, hago un for para recorrer de uno en uno y otro para recorrer el mismo arreglo pero a partir de la variable del primer for más uno. De esta forma estoy obteniendo los elementos del arreglo de dos en dos, esto lo necesito porque tengo que imprimir todas las líneas del archivo del índice 1 obtenido con el for hasta el índice 2.

Espero que me hayas entendido, el archivo html es muy largo por eso no lo incluí, pero anexo una parte del archivo explicándotelo a detalle.

Gracias.

Este es el archivo, las marcas no tienen importancia: después voy a quitarlos.

Como ves, existen http://, esos son los patrones, entonces obtengo en un arreglo la línea 1 y 18, por lo regular, cada URL es un separador de archivo html. Lo que necesito es entonces ubicar estos separadores para mostrar todas las líneas que estén entre estos http. Por eso hago los for: para recorrer de dos en dos y un tercero para recorrer del primer http al segundo e imprimir las líneas que estén entre esos dos http en un archivo diferente.

Sintáxis: [ Descargar ] [ Ocultar ]
Using html4strict Syntax Highlighting
  1. http://serpiente.dgsca.unam.mx/jornada/2000/ene00/000118/anteriores.html
  2. <!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN">
  3. <HTML><HEAD>
  4. <TITLE>404 Not Found</TITLE>
  5. </HEAD><BODY>
  6. <H1>Not Found</H1>
  7. The requested URL /2000/ene00/000118/anteriores.html was not found on this server.<P>
  8. </BODY></HTML>
  9.  
  10. <FONT SIZE=3>La Jornada martes 18 de enero de 2000</FONT><P>
  11.  
  12. <FONT SIZE=3>ASTILLERO ¤ <B>Julio Hern&aacute;ndez López</B></FONT><p>
  13.  
  14. <FONT SIZE=3><B>P</B>ocas veces ganan presencia p&uacute;blica los conflictos internos del PAN. Por lo regular, las desavenencias entre los grupos e intereses que confluyen en el partido <I>blanquiazul</I> se resuelven de manera silenciosa, discreta, como se deben arreglar los problemas en toda familia decente. </FONT>
  15. <P>
  16. <FONT SIZE=3><B>S</B>in embargo, ansioso de promover cambios en la vida p&uacute;blica de la naci&oacute;n, Vicente Fox ha logrado, ya, generar uno muy importante en su propio partido: le ha convertido en piedra de esc&aacute;ndalo, en bastimento para las lenguas de los lavaderos pol&iacute;ticos, en lentejuela de vestuarios de pasarela.</FONT>
  17.  
  18. http://serpiente.dgsca.unam.mx/jornada/ ... llero.html
  19. </html><body>
Coloreado en 0.002 segundos, usando GeSHi 1.0.8.4
diana
Perlero nuevo
Perlero nuevo
 
Mensajes: 8
Registrado: 2005-07-01 20:27 @894

Notapor kidd » 2005-07-11 16:46 @740

Hola, Diana.

A ver si entiendo: tienes un archivo el cual contiene varias páginas HTML unidas y lo que quieres hacer es separar esas páginas dentro del archivo, tomando las líneas que empiezan con http:// como separador.

Avísame si estoy en lo correcto, pues de ser así me parece que estás tomando un camino demasiado largo.

SALUDOS

P.D. Si quieres puedes mandarme una copia del archivo en un .zip a mi correo para ver de qué se trata.
Uriel Lizama Perl programmer fundador de Perl en Español
Perl Programming Language
Avatar de Usuario
kidd
Creador de Perl en Español
Creador de Perl en Español
 
Mensajes: 1166
Registrado: 2003-10-15 16:52 @744
Ubicación: México

Notapor diana » 2005-07-12 19:18 @846

Exactamente eso es lo que necesito. Apenas estoy aprendiendo Perl y no encontré otra forma más sencilla de hacerlo ya que debo localizar las líneas de los http para jalar cada html en archivos diferentes. Te mando a tu correo el html zipeado.

Gracias :o
diana
Perlero nuevo
Perlero nuevo
 
Mensajes: 8
Registrado: 2005-07-01 20:27 @894

Lo que necesitas.

Notapor sonic07 » 2005-07-13 09:48 @450

Hola, Diana.

Pues bueno, tomé de base tu código y pues este código lo que hace es separarte el html cada vez que encuentra la línea:

"http:\/\/serpiente.dgsca.unam.mx\/jornada\/2000\/ene00\/000118\/"

Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1. #!/usr/bin/perl
  2.  
  3. $entrada = $ARGV[0];
  4. $salida  = $ARGV[1];
  5.  
  6. if ( $entrada eq "" || $salida eq "" ) {
  7.     die "\nuse: perl ejemplito.pl entrada.html salida.txt\n";
  8. }
  9.  
  10. open( ENTRADA, "$entrada" )  || die "no se pudo abrir el archivo: $!\n";
  11. open( SALIDA,  "+>$salida" ) || die "no se pudo abrir $salida: $!\n";
  12.  
  13. $num     = 0;
  14. $varLine = 0;
  15. my %lineas = ();
  16. $texto = "";
  17. $l     = "http:\/\/serpiente.dgsca.unam.mx\/jornada\/2000\/ene00\/000118\/";
  18.  
  19. while ( $linea = <ENTRADA> ) {
  20.  
  21.     if ( ( $linea =~ /$l/ ) ) {        #Aqui te valida la expresion.
  22.         $linea = <ENTRADA>;            #Lee la siguiente, para que me sirva el while.
  23.         while ( $linea !~ /$l/ ) {     #Mientras la expresion regular no se parezca
  24.                                        #Sigue entrando y leyendo.
  25.             print $linea;
  26.  
  27.             $linea = <ENTRADA>;
  28.         }
  29.  
  30.         #Cuando sale te pone un marcador, esto sirve para acotarte el texto
  31.         #que es el que necesitas, solo necesitas meter en el segundo while una estructura para almacenarlo.
  32.         print "++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++";
  33.         $num++;
  34.  
  35.     }
  36.  
  37.     $varLine++;
  38. }                                      #end while
  39. print "\n", $varLine, "\n";
  40. print $num, "\n";
Coloreado en 0.002 segundos, usando GeSHi 1.0.8.4


Espero te sirva,
Saludos,
Sonic. :wink:
sonic07
Perlero nuevo
Perlero nuevo
 
Mensajes: 1
Registrado: 2005-07-12 18:45 @822

Notapor diana » 2005-07-21 19:32 @856

Gracias, sonic. El código sí me sirvió. Únicamente tiene un detalle: que solo muestra la mitad de los archivos, pero ya lo arreglé, solo me falta generar los archivos e imprimir el texto que le corresponde a cada uno. Cuando lo tenga listo lo mando al foro para ver si a alguien le sirve.

Bye
diana
Perlero nuevo
Perlero nuevo
 
Mensajes: 8
Registrado: 2005-07-01 20:27 @894

Re: Recorrer rangos de lineas de archivo en un arreglo

Notapor explorer » 2005-07-24 19:45 @864

Lo que sigue es la solución 'compleja', pero quiero que se tome como ejemplo de la potencia del lenguaje Perl.

Problema:
Tenemos un fichero de texto compuesto de varias páginas HTML, separadas cada una de ellas por su enlace URI completo, algo así:

Sintáxis: [ Descargar ] [ Ocultar ]
Using text Syntax Highlighting
<URL>
<contenido de la página del URL anterior>
<URL>
<contenido de la página del URL anterior>
...
Coloreado en 0.000 segundos, usando GeSHi 1.0.8.4


Queremos hacer un programa que lea este archivo, divida el contenido de cada subpágina, y lo grabe en un fichero html distinto, cada uno de ellos extraído del propio URL indicado en la primera línea.

Una posible solución podría ser esta:
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1. use URI;                      # Nos servirá para extraer el nombre del fichero
  2.  
  3. # Leer todo el texto
  4. #     Redefinimos la variable especial $/ para que <> se coma todo el texto de un bocado :-)
  5. #     No hace falta hacer un close, porque estamos dentro de un contexto {}
  6. $html = do { local $/; open F,"<entrada.html"; <F> };
  7.  
  8. # Dividir en partes según el http://
  9. #     Utilizamos el http como separador
  10. #     En partes quedarán todos los ficheros, incluso con los http (notar que usamos () en el split)
  11. @partes = split /^(http:.+?)$/m, $html;
  12.  
  13. # Para todas las partes, incluyendo los URL separadores
  14. foreach ( @partes ) {
  15.     next unless $_;   # Quitamos el caso de líneas vacías al principio o final del fichero (una consecuencia de usar split)
  16.  
  17.     if ( /^http/ ) {        # Si es un enlace
  18.         # Extraemos el nombre del fichero
  19.         #    creamos un URI en base al URL leído
  20.         #    lo partimos en cachos, y
  21.         #    nos quedamos con el último (se supone que siempre es un nombre de fichero)
  22.         $fichero = (URI->new($_)->path_segments)[-1];
  23.         print "Grabando fichero: $fichero\n";
  24.         next;              # Seguimos con el bucle
  25.     }
  26.     # Guardamos el nuevo fichero con el trozo de html
  27.     #     Otra línea compacta: abrimos el fichero
  28.     #     y guardamos el contenido de $_ en $fichero
  29.     #     Lo mismo de antes, no hace falta usar close
  30.     do { open SALIDA,">$fichero"; print SALIDA };
  31. }
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4

Repito que es algo complicado para alguien que empieza, incluso hay cosas que no es recomendable usarlas, como lo de no poner close(). Esto sólo es un ejemplo de cómo se resolvería un problema de forma rápida (en 10 líneas de código), no como ejemplo a seguir.
JF^D Perl programming & Raku programming. Grupo en Telegram: https://t.me/Perl_ES
Avatar de Usuario
explorer
Administrador
Administrador
 
Mensajes: 14480
Registrado: 2005-07-24 18:12 @800
Ubicación: Valladolid, España


Volver a Básico

¿Quién está conectado?

Usuarios navegando por este Foro: No hay usuarios registrados visitando el Foro y 3 invitados