如何查找旧的大文件并为包含这些文件的目录生成度量



我是一名在设计部门工作的硬件工程师,我们经常生成包含大量数据的目录(包括大文件和包含大量小文件的目录)。这些数据可能会在磁盘上停留很长一段时间,我正在寻找一种指标来识别其中有大量旧数据的目录作为删除的候选目录。

我决定的指标是文件大小(以M为单位)*文件期限(以天为单位)。

我有一个可行的解决方案,但它是shell脚本和c的结合,既不可维护,也不美观,也不优雅。

我正在寻找改进剧本的想法。

基本思想是使用find生成所有文件的原始数据

find $Dir -type f -exec stat -c "%s,%Y,%n" {} ; > rpt3

然后在C中处理该文件以获得格式的文件(rpt3b)

度量、年龄、大小、文件名

度量为年龄*尺寸

Age是自修改文件以来的天数

Size是M 中文件的大小

FileName是文件的名称。

然后我处理这个文件,对每个目录的指标进行汇总

for Directory in $( find /projects/solaris/implementation -maxdepth 4 -type d ) ; do
Total=`grep $Directory/ rpt3a | sed -e 's?,.*??' | paste -sd+ - | bc`
echo $Total,$Directory >> rpt3c
done

因此,输出类似于du,但报告的是度量,而不是磁盘上的大小。

我可以完成C程序的最后一步,但我正在寻找一个在一个环境中理想工作的解决方案(不必是C,我对学习新语言持开放态度)。

提前感谢

您可以用Perl完成全部工作。Perl附带了两个运算符-M-s,它们分别是文件的年龄(以天为单位)和文件的大小(以字节为单位)。这里的年龄是脚本开始时间减去文件修改时间,还有模仿find命令的File::Find模块。

#!perl
use strict;
use warnings;
use File::Find;
find(&process, shift); # shift the start directory off @ARGV
sub process {
# Lots of use of the magic _ file handle so we don't keep having to call stat()
print( (-M _) * (-s _), ' ', -M _, ' ', -s _, " $File::Find::namen")
if -f $_;
}

使用cut从提取的行中提取正确的列来代替sed。CCD_ 6将提取各自由CCD_ 7分隔的第三列。

带输入:

10,2,5,a/b
20,4,5,a/c
30,2,15,b/d
40,4,10,a/d

命令grep a/ a.txt | cut -f3 -d, | paste -sd+ - | bc将产生:

20

和命令grep b/ a.txt | cut -f3 -d, | paste -sd+ - | bc:

15

调用'python script.py startdir ~/somefile.txt'

您可以将此作为起点:

import os
import sys
import time
def get_age_in_days(file_stats):
"""Calculate age in days from files stat."""
return (time.time() - file_stats.st_mtime) // (60*60*24) 
def get_size_in_MB(file_stats):
"""Calculate file size in megabytes from files stat."""
return file_stats.st_size / (1024 * 1024)
def metric(root,f):
"""Uses root and f to create a metric for the file at 'os.path.join(root,f)'"""
fn = os.path.join(root,f)
fn_stat = os.stat(fn) 
age = get_age_in_days(fn_stat)
size = get_size_in_MB(fn_stat)
metric = age*size
return [metric, age, size, fn] 
path = None
fn   = None
if len(sys.argv)==3:
path = sys.argv[1]
fn = sys.argv[2]
else:
sys.exit(2)

with open(fn,"w") as output:  
# walk directory recursivly and report anything with a metric > 1 
for root,dirs,files in os.walk(path):
total_dict = 0
for f in files:
m = metric(root,f)
# cutoff - only write to file if metric > 1
if m[0] > 1: 
total_dict += m[0]
output.write(','.join(map(str,m))+"n")
output.write(','.join([str(total_dict), "total","dictionary",root])+"n")
# testing purposes
# print(open(fn).read())

示例文件-(无截断-使用https://pyfiddle.io/):

0.0,0.0,0.0011606216430664062,./main.py
0.0,0.0,0.0,./myfiles.txt
0.0,total,dictionary,./

您可以查找包含,total,dictionary,:0.0,total,dictionary,./的任何一行,以获取字典总计。

相关内容

最新更新