2010-09-18 10 views
5

Tengo varios registros de acceso en el directorio de registros, siguiendo la convención de nombres a continuación:¿Cómo puedo tratar muchos archivos de registro como un archivo virtual en Perl?

access.log.1284642120 
access.log.1284687600 
access.log.1284843260 

Básicamente, los registros son "girado" por Apache por día, por lo que se pueden ordenar en orden.

Estoy tratando de "leerlos uno tras otro", para que puedan ser tratados como un solo archivo de registro.

my @logs = glob('logs/access.log.*'); 

El código anterior glob todos los registros, pero no estoy seguro:

  • ¿En qué orden se organizarán los registros, en orden alfabético?
  • si deseo verificar "el último tiempo de acceso desde una única IP", ¿cómo podría hacerlo?

Tengo un script de Perl que puede leer un solo registro de acceso y comprobarlo fácilmente (mi algoritmo es tener un gran hash que usa la dirección IP como clave y el tiempo de acceso como el valor, y seguir presionando pares de clave/valor ...). Pero no quiero simplemente fusionar todos los archivos de acceso en un solo archivo temporal solo para este proceso.

¿Alguna sugerencia? Muchas gracias de antemano.

Respuesta

11

Si desea garantizar un orden determinado, más o menos lo mismo, aunque sólo sea para asegurarse de que va a salir bien:

my @files = sort { ... } glob(...); 

En este caso, en que los nombres de archivo son todos iguales excepto por los dígitos particulares, puede que no necesite el bloque para ordenar:

my @files = sort glob(...); 

leerlas como una súper-archivo, me gusta usar un local @ARGV para que pueda utilizar el operador de diamante, que es en realidad la magia ARGV gestor de archivo . Cuando llega al final de un archivo en @ARGV, pasa al siguiente. Este falsificaciones especificando todos los archivos en la línea de comandos mediante la asignación a @ARGV dentro del programa:

{ 
local @ARGV = sort { ... } glob(...); 

while(<>) { 
     ...; 
     } 
} 

Si lo que necesita saber el archivo que está procesando en ese momento, busque en $ARGV.

Si necesita algo más elegante, puede que tenga que recurrir a la fuerza bruta.

+1

+1 de puntuacion. Al igual que las bandas de metal, las respuestas SO son mejores con diéresis. – FMc

+0

También obtiene la magia de '$ .' haciendo un seguimiento del número de línea actual del archivo actual. – mob

2

En un entorno Unix-y, puede aprovechar la cáscara para agrupar los archivos juntos:

my @files = glob("$dir/access.log.*"); 
open my $one_big_logfile, "-|", "cat @files" or die ...; 
while (<$one_big_logfile>) { 
    ... 
} 
Cuestiones relacionadas