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

时间:2019-01-02 11:59:05

标签: python c perl sh

我是设计部门的一名硬件工程师,我们通常会生成包含大量数据的目录(大型文件和包含大量小文件的目录)。这些数据可以在磁盘上徘徊一段时间,我正在寻找一种指标来识别其中包含大量旧数据的目录作为删除对象。

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

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

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

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

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

然后用C语言处理该文件以获取格式为(ptt3b)的文件

指标,年龄,大小,文件名

指标是年龄*大小

年龄是文件被修改以来的天数

大小是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,我愿意学习新语言)。

预先感谢

3 个答案:

答案 0 :(得分:4)

您可以在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::name\n")
        if -f $_;
}

答案 1 :(得分:0)

使用cut代替sed从提取的行中提取正确的列。 cut -d, -f3将提取第三列,每列由,分隔。

使用输入:

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

答案 2 :(得分:0)

致电# filename popper.py from kivy.app import App from kivy.uix.popup import Popup from kivy.uix.stacklayout import StackLayout from kivy.uix.boxlayout import BoxLayout from kivy.lang import Builder Builder.load_string(''' #:import Factory kivy.factory.Factory <MyBox>: orientation:'vertical' TextInput: text: 'N/A' Button: text: 'Choose a name' on_press: Factory.Pop().open() <Pop>: auto_dismiss: False title: 'Names' size_hint: [0.4, 0.5] pos_hint:{'right': 0.4, 'top': 1} id: msg_box GridLayout: id: _pop rows: 3 GridLayout: id: pop_grid cols:2 padding: [0,5] Spinner: text: 'First Name' id: fn sync_height: True values: ['andrew', 'brian', 'colin', 'david', 'edmond'] width: self.width on_text: self.text = app.root.capitalise(self.text) Spinner: text: 'Last Name' id: ln sync_height: True values: ['Adams', 'Bass', 'Carney', 'Davies', 'Edmonds'] width: self.width Button: padding: [0,5] text: 'OK' on_release: root.dismiss() width: self.width <MyLayout>: orientation: 'tb-lr' size_hint: .2, 0.5 width: self.width Button: text: 'Create name box.' on_press: app.root.make_name_box() width: 300 ''') class MyLayout(StackLayout): pass def make_name_box(self): self.add_widget(MyBox()) def capitalise(self, text): return text.capitalize() class Pop(Popup): def __init__(self, **kwargs): super(Pop, self).__init__(**kwargs) class MyBox(BoxLayout): def __init__(self, **kwargs): super(MyBox, self).__init__(**kwargs) size_hint = None, None width = 300 class PopperApp(App): def build(self): return MyLayout() if __name__ =='__main__': PopperApp().run()

您可以以此为起点:

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

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

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())

您可以查找包含 0.0,0.0,0.0011606216430664062,./main.py 0.0,0.0,0.0,./myfiles.txt 0.0,total,dictionary,./ 的任何行:,total,dictionary,以获得字典总计。