• Publicidad

Dividir un archivo por líneas

¿Ya sabes lo que es una referencia? Has progresado, el nível básico es cosa del pasado y ahora estás listo para el siguiente nivel.

Notapor creating021 » 2006-12-18 19:07 @838

explorer escribiste:La coma no sirve para concatenar strings.

:oops: cierto, que pena de verdad, no sirve.
Expect the worst, is it the least you can do?
Avatar de Usuario
creating021
Perlero frecuente
Perlero frecuente
 
Mensajes: 595
Registrado: 2006-02-23 16:17 @720
Ubicación: Frente al monitor

Publicidad

Notapor nany » 2006-12-19 11:51 @535

gracias por sus respuestas la verdad me ha costado un poco de trabajo este lenguaje saludos!!!!!
nany
Perlero nuevo
Perlero nuevo
 
Mensajes: 17
Registrado: 2006-12-11 13:36 @608

Notapor Perl user » 2006-12-19 12:20 @555

explorer escribiste:Supongamos que has metido todas las líneas en el array @lineas.
Si suponemos también que el fichero puede tener entre 1 y 6000 líneas, tenemos que dividir su contenido entre uno o dos ficheros.
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
$fichero = "salida1";
@resto = splice( @lineas, 3_000 );
print "Salida en fichero 1 $fichero\n";
# Aquí grabamos las @lineas

++$fichero;
if ( @resto ) {
    print "Salida en fichero 2 $fichero\n";
    # Aquí grabamos el @resto
}
Coloreado en 0.009 segundos, usando GeSHi 1.0.8.4

Darse cuenta de que ni siquiera comprobamos si tenemos 3000 líneas, más o menos... Perl nos ahorra MUCHO trabajo.


No reinventemos el hilo negro, ya está hecho.

Tie::File hace estas tareas demasiado sencillas y triviales, como para evitarnos el uso de splice y lectura directa. Recordemos que Tie::File incluso tiene caching y otras monerías muy útiles.

Échenle un vistazo al módulo, no por algo está dentro de los Core modules de Perl.

Saludos.
Marco A. Manzo
[email protected]
http://www.unixmonkeys.com/amnesiac/
Perl Programming Language
Perl user
Maestro honorario
Maestro honorario
 
Mensajes: 271
Registrado: 2004-11-03 21:11 @924

Notapor nany » 2006-12-19 15:11 @674

Hola a todos. Bueno, el leer línea por línea ya me queda claro pero aún no he podido generar que de un archivo de supongamos 8500 líneas que se llama juanito me derive tres archivos uno con juanito1 con las primeras 3000 líneas, juanito2 con las siguientes 3000 líneas y juanito3 con las restantes. Este es mi código que aunque según ya no tiene errores no hace lo que pido. Ayuda.

Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
/Abrir Directorio
    opendir DIR, "$s_Dir" or die "ERR: Al leer directorio [ " . $s_Dir ."]\n";
    my @a_Archivos = readdir (DIR);
    close DIR;
###############///Abrir Archivo
sub leeArchivoArr{

    foreach my $s_NombreArchivo (@a_Archivos){
    my $s_Archivo = $s_Dir . "/" . $s_NombreArchivo;
    open IN, "$s_Archivo"  or die "ERR: Al abrir [ $s_Archivo ]\n";
     my $i_ContLineas = 0;
     my @a_Archivo = <IN>;
    print "INF: Archivo [$s_Archivo] con [$i_ContLineas ] Lineas\n";
    close IN;
###############///comparacion
       my $s_contArchivo1 = 0;
     while (scalar @a_Archivo >3000){

          my @a_arreglo3000 = splice (@a_Archivo,3000);
         my $s_archivonuevo = $ENV{"HOME"}."$s_NombreArchivo"."$s_contArchivo1";

          open OUT ,">$s_archivonuevo";
          print OUT "$s_Archivo\n";
          close OUT;
          $s_contArchivo1 ++;
          }

     if (@a_Archivo < 3000){
        my $s_contArchivo = 0;
        my $s_archivonuevo = $ENV{"HOME"}."$s_NombreArchivo" . "$s_contArchivo";

          open OUT ,">$s_archivonuevo";
          print OUT "$s_Archivo";
           close OUT;
          $s_contArchivo ++;
           }
}
Coloreado en 0.002 segundos, usando GeSHi 1.0.8.4
nany
Perlero nuevo
Perlero nuevo
 
Mensajes: 17
Registrado: 2006-12-11 13:36 @608

Notapor explorer » 2006-12-19 21:40 @944

Hay algunos errores de lógica. Hay algunas variables que nunca se usan o nunca han sido inicializadas.

Lo primero que he hecho es crear unos ficheros de prueba con el comando
Sintáxis: [ Descargar ] [ Ocultar ]
Using bash Syntax Highlighting
perl -le 'print "Linea ", ++$numero for 1..8500' > juanito
Coloreado en 0.003 segundos, usando GeSHi 1.0.8.4

El siguiente programa busca en el subdirectorio 'ficheros' todos esos ficheros generados antes y los divide, dejándolos en el directorio raíz, como pones en tu programa.
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
    1 #!/usr/bin/perl
    2
    3 use warnings;
    4 use strict;
    5
    6 my $s_Dir = 'ficheros';
    7
    8 ### Abrir Directorio
    9 opendir DIR, "$s_Dir" or die "ERR: Al leer directorio [ $s_Dir ]\n";
   10 my @a_Archivos = grep { -f "$s_Dir/$_" } readdir (DIR);
   11 close DIR;
   12
   13 ### Abrir Archivo
   14 foreach my $s_NombreArchivo ( @a_Archivos ) {
   15     my $s_Archivo = $s_Dir . "/" . $s_NombreArchivo;
   16     open IN, "$s_Archivo" or die "ERR: Al abrir [ $s_Archivo ]\n";
   17     my @a_Archivo = <IN>;
   18     print "INF: Archivo [$s_Archivo] con [", scalar @a_Archivo, "] Lineas\n";
   19     close IN;
   20
   21     ### Comparación
   22     my $s_contArchivo1  = 1;
   23     while ( @a_Archivo > 3000 ) {
   24         my @a_arreglo3000 = splice(@a_Archivo, 0, 3000);
   25         my $s_archivonuevo = $ENV{"HOME"}."/$s_NombreArchivo$s_contArchivo1";
   26
   27         print "INF: Archivo salida [$s_archivonuevo]\n";
   28         open OUT ,">$s_archivonuevo";;
   29         print OUT @a_arreglo3000;
   30         close OUT;
   31         $s_contArchivo1++;
   32     }
   33
   34     if (@a_Archivo <= 3000) {
   35         my $s_archivonuevo = $ENV{"HOME"}."/$s_NombreArchivo$s_contArchivo1";
   36
   37         print "INF: Archivo salida [$s_archivonuevo]\n";
   38         open OUT ,">$s_archivonuevo";
   39         print OUT @a_Archivo;
   40         close OUT;
   41         $s_contArchivo1++;
   42     }
   43 }
Coloreado en 0.002 segundos, usando GeSHi 1.0.8.4
* En las líneas 3 y 4 activamos unos pragmas para que nos ayuden a programar bien
* En la décima vamos leyendo todos los ficheros del directorio, pero sólo nos quedamos con aquellos que sean realmente ficheros normales (-f)
* El bucle de la decimo cuarta y siguientes analiza todos esos ficheros. Por cada uno lo abrimos y lo leemos entero
* Luego comienza la división. Con el bucle while repetimos mientras tengamos más de tres mil líneas
* En la línea vigésimo cuarta obtenemos las primeras tres mil líneas
* Y las grabamos en la vigésimo novena
* En la trigésimo primera, incrementamos el contador sufijo del nombre de salida
* El if de las líneas trigésimo cuarta y siguientes hacen lo mismo con el resto del fichero. Realmente no es necesario este if porque sabemos que ahí el fichero siempre tiene menos de tres mil líneas

Una mejora en la lógica sería: vamos a partir un fichero mientras tengamos algo que partir:
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
    1 #!/usr/bin/perl
    2
    3 use warnings;
    4 use strict;
    5
    6 my $s_Dir = 'ficheros';
    7
    8 # Abrir Directorio
    9 opendir DIR, "$s_Dir" or die "ERR: Al leer directorio [ $s_Dir ]\n";
   10 my @a_Archivos = grep { -f "$s_Dir/$_" } readdir (DIR);
   11 close DIR;
   12
   13 ### Abrir Archivo
   14 foreach my $s_NombreArchivo ( @a_Archivos ) {
   15     my $s_Archivo = $s_Dir . "/" . $s_NombreArchivo;
   16     open IN, "$s_Archivo" or die "ERR: Al abrir [ $s_Archivo ]\n";
   17     my @a_Archivo = <IN>;
   18     print "INF: Archivo [$s_Archivo] con [", scalar @a_Archivo, "] Lineas\n";
   19     close IN;
   20
   21     ### Comparación
   22     my $s_contador = 1;
   23     while ( @a_Archivo ) {
   24         my @a_arreglo3000 = splice(@a_Archivo, 0, 3000);
   25         my $s_salida = "$ENV{HOME}/$s_NombreArchivo$s_contador";
   26         print "INF: Archivo salida [$s_salida]\n";
   27         open OUT ,">$s_salida";
   28         print OUT @a_arreglo3000;
   29         close OUT;
   30         $s_contador++;
   31     }
   32 }
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4
Los únicos cambios están en la parte de Comparación:
* En la línea 22 tenemos una variable contador que se encargará del sufijo
* La línea siguiente es la base de la lógica: mientras tengamos líneas qué repartir...
* ... sacamos 3000 de ellas con splice en la línea siguiente
* Las imprimimos, y listo.

Claro que... si estuvieras en Unix, este problema lo tendrías resuelto con el comando 'split':
Sintáxis: [ Descargar ] [ Ocultar ]
Using bash Syntax Highlighting
split -l 3000 -a 1 -d juanito juanito
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4
JF^D Perl programming & Raku programming. Grupo en Telegram: https://t.me/Perl_ES
Avatar de Usuario
explorer
Administrador
Administrador
 
Mensajes: 14476
Registrado: 2005-07-24 18:12 @800
Ubicación: Valladolid, España

Notapor nany » 2006-12-20 13:32 @605

Muchas, muchas gracias, de verdad. Me ayudaste mucho; ojalá pueda seguir consultándolos.
Saludos
nany
Perlero nuevo
Perlero nuevo
 
Mensajes: 17
Registrado: 2006-12-11 13:36 @608

Anterior

Volver a Intermedio

¿Quién está conectado?

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