Cómo eliminar files de 2 meses atrás en Unix

Digamos que tengo abajo los files de logging

AA_XX_20130719185428.log exec_xxx_cpb_20130712182453.log 13122013121327_AR_INC_DOBC_1.dprf.log 24122013_masterscript.LOG 

La parte de date contiene tanto la date como la hora.

Quiero eliminar todos los files de 2 meses atrás.

No quiero eliminar el file en function de la date de la última modificación, sino en function de la date incluida en el nombre del file. Las dates pueden estar en cualquiera de estos formattings:

  • YYYYmmddHHMMSS
  • ddmmYYYYHHMMSS
  • ddmmYYYY.

¿Cómo puedo eliminar los files usando el script de shell?

Puedes usar el siguiente script. Llamar con nombres de files para probar y eliminar como arguments.

 #!/usr/bin/env python # encoding: utf-8 import os import sys import datetime test_file_names = [x for x in """\ AA_XX_20130719185428.log exec_xxx_cpb_20130712182453.log 13122013121327_AR_INC_DOBC_1.dprf.log 24122013_masterscript.LOG """.split('\n') if x.strip()] # appr. 2 meses two_months = datetime.date.today() - datetime.timedelta(days=61) testing = len(sys.argv) < 2 if testing: file_names = test_file_names else: file_names = sys.argv[1:] allow_datetime = set([ len('YYYYmmddHHMMSS'), len('ddmmYYYYHHMMSS'), len('ddmmYYYY'), ]) for file_name in test_file_names: for part in os.path.splitext(os.path.basename(file_name))[0].split('_'): if len(part) not in allow_datetime: continue for ch in part: if not ch.isdigit(): break else: dt = part if dt[4:6] == '20': # ddmmYYYY yy = int(dt[4:8]) mm = int(dt[2:4]) dd = int(dt[:2]) else: # YYYYmmdd yy = int(dt[:4]) mm = int(dt[4:6]) dd = int(dt[6:8]) try: d = datetime.date(yy, mm, dd) except ValueError: print 'wrong date', yy, mm, dd raise if testing: print '{:<6s} {:<40s} {}'.format( 'remove' if d < two_months else ' ', file_name, repr(d)) elif d < two_months: print 'removing', file_name os.remove(file_name) 

Si está usando la date GNU, puede aprovechar sus capacidades de manipulación de dates:

 #!/usr/bin/env bash ## Define the age limit lim=$(date -d "2 months ago" +%s); ## Find all files in the current directory and ## sub directories find . -type f | ## Extract the longest string of numbers (we assume that is the date) ## and change mmdd to ddmm perl -lne ' ## skip file names that don't have enough numbers /(\d{1,8})/ || next; $d=$1; next unless $d; ## Change YYYYmmddHHMMSS to mm/dd/YYY if($d=~/201\d$/){$d=~s|(\d{2})(\d{2})(\d{4})|$2/$1/$3|} ## Change ddmmYYYYHHMMSS or ddmmYYYY to mm/dd/YYY else{$d=~s|(\d{4})(\d{2})(\d{2})|$2/$3/$1|}; ## Print the original file name and the modified date string print "$_ $d" if ' | ## Read the file name into $f and the date into $d while read fd; do ## If this date is older than $lim, delete the file if [ "$(date -d "$d" +%s)" -lt "$lim" ]; then rm "$f"; fi done 

Esto se puede condensar en un "trazador de líneas" que puede copyr / pegar directamente en la terminal:

 lim=$(date -d "2 months ago" +%s); find . -type f | perl -lne ' /(\d{1,8})/ || next; $d=$1; if($d=~/201\d$/){$d=~s|(\d{2})(\d{2})(\d{4})|$2/$1/$3|} else{$d=~s|(\d{4})(\d{2})(\d{2})|$2/$3/$1|}; print "$_ $d"' | while read fd; do [ "$(date -d "$d" +%s)" -lt "$lim" ] && echo rm "$f"; done 

CAVEATS: esta solución asume que los nombres de sus files no contienen espacios y que la cadena de dígitos más larga en el nombre del file siempre será la date.

 find . -type f -mtime +60 -exec rm -f {} \; 

El -mtime usa el time de file modificado

 find . -type f -atime +60 -exec rm -f {} \; 

El time de acceso usa el time

también con ls -lc puedes ver el time de creación del inodo. Esto cambia cuando los datos de inodos se actualizan como en chmod, chown o chgrp, por ejemplo.