2011-05-23 44 views
5

Estoy desarrollando un script bash que necesita buscar archivos dentro de un solo directorio que son "antiguos" basados ​​en una variable que especifica cuántos días deben pasar antes el umbral se excede y los archivos están marcados para la acción (podría ser cualquier cosa, desde mover hasta archivar para eliminar, etc.). El problema es que el tiempo de modificación del archivo es irrelevante para determinar la antigüedad de los archivos antes de tomar medidas, ya que los archivos pueden modificarse con poca frecuencia, el tiempo de ejecución del script puede variar, etc.script bash para encontrar archivos antiguos basados ​​en la fecha en el nombre de archivo

El tiempo que determina que se mantienen los archivos es en el nombre real del archivo en forma de AAAA-MM-DD (o% F con el comando de fecha). tomar por ejemplo el nombre del archivo contents-2011-05-23.txt. ¿Qué comando (s) se podría ejecutar en este directorio para encontrar todos los archivos que exceden una cierta cantidad de días (tengo el umbral actualmente establecido en 7 días, podría cambiar) e imprimir sus nombres de archivo?

Respuesta

2

En BSD, la -j se usa para prevenir la fecha siendo establecido y el parámetro -f se usa para establecer el formato de la fecha de entrada. :

En primer lugar, es necesario encontrar la fecha de hoy en el número de días desde 1 de enero de 1970:

today=$(date -j -f "%Y-%m-%d" 1969-12-31 +%s) 

Ahora, se puede usar eso para averiguar el tiempo hace siete días:

((cutoff = $today - 604800)) 

El número 604800 es el número de segundos en siete días.

Ahora, para cada archivo en su directorio, necesita encontrar la parte de la fecha de la cadena. No sé de una mejor manera. (Tal vez alguien sabe algo de magia de Bash).

find . -type f | while read fileName 
do 
    fileDate=$(echo $foo | sed 's/.*-\([0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]\).*/\1/') 
    yadda, yadda, yadda #Figure this out later 
done 

Una vez que tenemos la fecha del archivo, podemos utilizar el comando date de averiguar si esa fecha en cuestión de segundos en menos de (y por lo tanto mayor que la fecha de corte)

today=$(date -j -f "%Y-%m-%d" 1969-12-31 +%s) 
((cutoff = $today - 604800)) 
find . -type f | while read fileName #Or however you get all the file names 
do 
    fileDate=$(echo $foo | sed 's/.*-\([0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]\).*/\1/') 
    fileDateInSeconds=$(date -j -f "%Y-%m-%d" $fileDate +%s) 
    if [ $fileDateInSeconds -lt $cutoff ] 
    then 
      rm $fileName 
    fi 
done 

En Linux, se utiliza el parámetro -d para definir la fecha que debe estar en formato YYYY-MM-DD:

today=$(date +"%Y-%m-%d) 

Ahora, se puede tomar eso y encontrar el número de segundos:

todayInSeconds=(date -d $today +%s) 

Todo lo demás debería ser más o menos lo mismo que el anterior.

0

Si ejecuta el comando diaria, usted puede hacer esto:

echo *-`date -d '8 days ago' '+%F'`.txt 

comodines adicionales podrían añadirse por supuesto

5

Crear un script bash isOld.sh así:

#!/bin/bash 

fileName=$1 
numDays=$2 

fileDt=$(echo $fileName | sed 's/^[^-]*-\([^.]*\)\..*$/\1/') 
d1=$(date '+%s') 
d2=$(date -d $fileDt '+%s') 
diff=$((d1-d2)) 
seconds=$((numDays * 24 * 60 * 60)) 
[[ diff -ge seconds ]] && echo $fileName 

A continuación, otorgue permiso de ejecución al archivo anterior ejecutando:

chmod +x ./isOld.sh 

Y, por último ejecutar este comando desde encontrar parte superior de su directorio para imprimir archivos de más de 7 días como:

find . -name "contents-*" -exec ./isOld.sh {} 7 \; 
+0

+1 Difícil de superar – leonbloy

0
find *[0-9][0-9][0-9][0-9]-[0-1][0-9]-[0-3][0-9]*.txt -exec bash -c 'dt=`echo $0 | sed -re "s/.*([0-9]{4}-[0-9]{2}-[0-9]{2}).*/\1/"`; file_time=`date -d $dt +%s`; cutoff_time=`date -d "31 days ago" +%s` ; test $file_time -lt $cutoff_time ' {} \; -print 

Esa es una de mis más largas trazadores de líneas uno :-) Aquí se envuelve de nuevo:

find *[0-9][0-9][0-9][0-9]-[0-1][0-9]-[0-3][0-9]*.txt \ 
    -exec bash -c ' dt=`echo $0 | \ 
        sed -re "s/.*([0-9]{4}-[0-9]{2}-[0-9]{2}).*/\1/"`; \ 
        file_time=`date -d $dt +%s`; \ 
        cutoff_time=`date -d "31 days ago" +%s` ;\ 
        test $file_time -lt $cutoff_time \ 
       ' {} \; -print 
Cuestiones relacionadas