Perl en Español

  1. Home
  2. Tutoriales
  3. Foro
  4. Artículos
  5. Donativos
  6. Publicidad
 

Comparar archivos por fecha

 
Publicar nuevo tema   Responder al tema    Foros de discusión -> Básico
Mensaje Vie Jul 18, 2008 12:58 pm
escanda
Perlero Nuevo
Perlero Nuevo
Registrado: 11 Jul 2008
Mensajes: 28
Comparar archivos por fecha Responder citando

Hola, ¿qué tal?

Me dirijo a ustedes en busca de ayuda.

Tengo una aplicación con la que accedo a un directorio y me fijo los archivos .txt que hay, y me los traigo.

Lo que necesito es que me los devuelva ordenados por fecha de creación.

Espero su ayuda..
gracias.

Acá les dejo el código actual, así se entiende un poco más.

Perl:
  #Abrimos el directorio
   
    my $dir = '\Desktop\Archivostxt/';

    opendir(DIR, $dir) or die $!;

    #lo abrimos.
    while (my $file = readdir(DIR)) {

       
        next unless (-f "$dir/$file");

        # buscamos solo los archivos .txt
        next unless ($file =~ m/\.txt$/);
            @propiedades = stat($file) <=> time();
            #@propiedades = time() - stat($file);
        my @archivos=$file;
                print ("@archivos");
                print("@propiedades");
    }
    closedir(DIR);


Eso me devuelve text1.txttext2.txt y lo que haya, pero necesito que me los devuelva ordenados por fecha de creación.
Mensaje Vie Jul 18, 2008 2:08 pm
kidd
Creador de Perl en Español
Creador de Perl en Español
Registrado: 15 Oct 2003
Mensajes: 1366
Ubicación: México
Responder citando

Umm, una solución rápida pero quizá no muy eficiente:

Perl:
my @archivos_ordenados = sort { -M $a <=> -M $b } readdir(DIR);
Mensaje Vie Jul 18, 2008 3:15 pm
explorer
Moderador
Moderador
Registrado: 24 Jul 2005
Mensajes: 4035
Ubicación: Valladolid, España
Responder citando

Esta es otra solución.
Perl:
#!/usr/bin/perl
use strict;
use warnings;

my $dir = '/home/explorer/Documents/';
my @archivos;

opendir(DIR, $dir) or die "$!\n";

while ( my $fichero = readdir(DIR) ) {

    # buscamos solo los archivos .txt
    next if $fichero !~ m/\.txt$/;

    my $archivo = $dir . $fichero;

    push @archivos, [ ((stat($archivo))[10]), $fichero ];
}

#use Data::Dumper;
#print Dumper(@archivos);

my @archivos_ordenados = sort { $a->[0] <=> $b->[0] } @archivos;

foreach my $fichero ( @archivos_ordenados ) {
    print $fichero->[1], "\n";
}

closedir(DIR);

Usamos el valor número 10 del valor devuelto por stat(), para comparar por la fecha de creación.

La solución de kidd es mucho más elegante, desde luego.
Mensaje Lun Jul 21, 2008 7:12 am
escanda
Perlero Nuevo
Perlero Nuevo
Registrado: 11 Jul 2008
Mensajes: 28
Responder citando

Muchas gracias por la respuesta, pero tengo un problema: me dice que hay un error al imprimir
Perl:
("print $fichero->[1], "\n";")


¿Por qué motivo puede ser?
Desde ya muchas gracias.
Mensaje Lun Jul 21, 2008 7:15 am
explorer
Moderador
Moderador
Registrado: 24 Jul 2005
Mensajes: 4035
Ubicación: Valladolid, España
Responder citando

Creo que esa línea está mal escrita...

Seguro que el error, si no es esta línea, está en una línea anterior.

Para comprobar que el programa está bien escrito, ejecuta perl -c programa.pl.
Mensaje Lun Jul 21, 2008 7:25 am
escanda
Perlero Nuevo
Perlero Nuevo
Registrado: 11 Jul 2008
Mensajes: 28
Responder citando

Ahora me encargaré de eso, pero también me aparece este error:
Código:
"Argument "prueba.txt" isn't numeric in numeric comparision <<=>> at directorio"

¿Por qué puede ser eso? Si se supone que me compara las horas de creación.
Mensaje Lun Jul 21, 2008 11:05 am
explorer
Moderador
Moderador
Registrado: 24 Jul 2005
Mensajes: 4035
Ubicación: Valladolid, España
Responder citando

No está bien creado la estructura de @archivos.

Descomenta las líneas
Perl:
use Data::Dumper;
print Dumper(@archivos);

y podrás ver qué estructura tiene. Debe aparecer un array de arrays. Los arrays pequeños deben contener, en su primer elemento, la fecha de creación y el segundo, el nombre.

Si no hay dos componentes, y solo uno, entonces es que stat() no ha devuelto nada en su componente número 10. Eso depende del sistema operativo en que te encuentres. ¿Cuál es?

Prueba a cambiar 10 por 9, para ver si así te devuelve algo. Estarás cambiando la fecha de creación por la fecha de última modificación.

Prueba también a ejecutarlo antes desde la línea de comandos, y así sabes si devuelve algo:
bash:
perl -le 'print +(stat("fichero.txt"))[10]'
Mensaje Lun Ago 18, 2008 4:09 pm
Jabarca
Perlero Nuevo
Perlero Nuevo
Registrado: 18 Ago 2008
Mensajes: 3
Responder citando

Hola
Primero agradecer el espíritu de colaboración para con los que estamos comenzando en esto =) "Muchas Gracias"

Bueno, soy principiante en esto y me han dado una tarea muy similar al problema de escanda, nada más que solo necesito recuperar el penúltimo archivo del directorio.

He intentado direccionarlo sin el foreach, directamente, pero no he dado con la solución Sad si me dan una mano se los agradeceré.

Saludos
Mensaje Lun Ago 18, 2008 4:57 pm
explorer
Moderador
Moderador
Registrado: 24 Jul 2005
Mensajes: 4035
Ubicación: Valladolid, España
Responder citando

Bienvenido a los foros de Perl en Español, Jabarca.

Si en @archivos están todos los archivos... y $archivos[-1] almacena el último archivo... entonces $archivos[-2] almacenará el penúltimo...
Mensaje Mar Ago 19, 2008 7:54 am
Jabarca
Perlero Nuevo
Perlero Nuevo
Registrado: 18 Ago 2008
Mensajes: 3
Responder citando

Explorer, primero muchas gracias por atender mi consulta Smile

Ahora mejor expongo el código que estoy usando para que se pueda entender mejor:

Perl:
use strict;
use warnings;

my $dir = "\\\\X1pegasus01\\LogCustomPage\\";
my @archivos;
opendir(DIR, $dir) or die "$!\n";

while ( my $fichero = readdir(DIR) ) {
    next if $fichero !~ m/\.txt$/;
    my $archivo = $dir . $fichero;
    push @archivos, [ ((stat($archivo))[10]), $fichero ]
}

my @archivos_ordenados = sort { $a->[0] <=> $b->[0] } @archivos;
print $archivos_ordenados[-2], "\n";
closedir(DIR);


La salida de este código es: ARRAY(0x184b310)

Para ver el contenido de @archivos_ordenados
Perl:
foreach my $fichero ( @archivos_ordenados ) {
    print $fichero->[1], "\n";
}


el resultado es:

Código:
2008 08 11.txt
2008 08 12.txt
2008 08 13.txt
2008 08 14.txt
2008 08 15.txt
2008 08 16.txt
2008 08 17.txt
2008 08 18.txt
2008 08 19.txt


Donde yo necesito recuperar el archivo del día anterior “2008 08 18.txt” para pasarlo como parámetro a una función.

Otra cosa, ¿algún consejo para un buen manual en español? Aun no he podido hacerme de un libro así que me limito a manuales en la red. Nuevamente, muchas gracias.
Mensaje Mar Ago 19, 2008 8:11 am
explorer
Moderador
Moderador
Registrado: 24 Jul 2005
Mensajes: 4035
Ubicación: Valladolid, España
Responder citando

Entonces, será
Perl:
print $archivos_ordenados[-2]->[1], "\n";

@archivos_ordenados es un array, con lo que nos quedamos con el penúltimo (-2) elemento. Y ese elemento es una referencia a otro array, que desreferenciamos con la flecha (->) y del array final, nos quedamos con el segundo elemento ([1]). Vamos, casi lo mismo que en lenguaje C.

Más información, en perldsc, perllol y perlreftut.

En cuanto a documentación, tienes por dónde empezar, y luego, seguir leyendo.

Y la sección de Tutoriales y Artículos de este sitio web, claro.
Mensaje Mar Ago 19, 2008 8:36 am
Jabarca
Perlero Nuevo
Perlero Nuevo
Registrado: 18 Ago 2008
Mensajes: 3
Responder citando

Bueno Explorer, me falta experiencia en programación... ya aprenderé Smile

Me has sido de gran ayuda. Muchas gracias por tu voluntad de enseñar.
Publicar nuevo tema   Responder al tema    Foros de discusión -> Básico Todas las horas son GMT - 6 Horas
Página 1 de 1



Powered by phpBB © 2001, 2005 phpBB Group