perl脚本之__分类统计某一目录下指定类型文件的大小

本文介绍了一款用于Samba共享环境下,针对特定文件类型(如mp3、图片等)进行磁盘空间占用统计的Perl脚本。该脚本分为两部分:第一部分查找指定目录下的文件,并记录文件路径与大小;第二部分则根据第一部分生成的数据进行汇总分析,统计每个用户的文件占用情况。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

先介绍一下写此脚本的背景,我们使用samba共享,每个人都有自己的个人目录,和群组共用目录,现在发现磁盘空间消耗的很厉害,上服务查一下才发现在,好多人在个人目录下放了好多mp3,图片,视频之类的文件,为了提高服务器利用率,所以决定对服务器上这此文件都进行统计,然后通知个人进行处理,不然就删除。

脚本分成两部分,第一查找出指定目录下所指定查找类型的文件(mp3,jpeg,etc.),把文件路径和大小写入指定文件,第二部分是对第一步生成那个文件进行分析,统计出每个人的个人目录下,每种文件总大小,

个人文件夹路径模式如下:/data/incoming/username/music/xxxx.mp3

第一部分代码:

#!/usr/bin/perl -W
#
# File: find_file.pl
# Author:sunrocs
# License: GPL-2

use strict;
use warnings;
my $ori_dir=shift;
chomp($ori_dir);
my $to_file=(split(////,$ori_dir))[2].".txt"; #

sub lsr_s($) {
my $cwd = shift;
my @dirs = ($cwd.'/');

my ($dir, $file);
while ($dir = pop(@dirs)) {
    local *DH;
    if (!opendir(DH, $dir)) {
        warn "Cannot opendir $dir: $! $^E";
        next;
        }
    foreach (readdir(DH)) {
        if ($_ eq '.' || $_ eq '..') {
            next;
            }   
        $file = $dir.$_;
        if (!-l $file && -d _) {
            $file .= '/';
            push(@dirs, $file);
            }
        &process($file,$dir);
        }
    closedir(DH);
    }
}

my ($sizecnt) = (0);

sub process($$) {
my $file = shift;
if ($file=~/(/.rmvb|/.mpg|/.mpeg|/.wmv|/.rm|/.avi|/.mp3|/.jpeg|/.jpg|/.png|/.gif)$/) {
    my $size= -s $file;
    $sizecnt+=$size;
    $file=~/.*//.+/.(/w+)$/;
    my $type=$1;
    &write_to_file($file,$size,$type);
    }
}

sub write_to_file {
    my ($file,$size,$type)=@_;
    my $line=$file."###".$size."###".$type."/n";
    open FH,">>$to_file" or die $!."/n";
    print FH  $line;
    close(FH);
}
lsr_s($ori_dir);
&write_to_file($ori_dir."/total/",$sizecnt,"total");

生成文件内容格式如下:
/data/incoming/zhangs/photos/test.jpg###63712###jpg
......
/data/incoming/total/###19000000###total



第二部分代码是对第一部分生成的文件进行分析,代码如下:

#!/usr/bin/perl
use strict;
my $file=shift;
chomp($file);
my $to_file="total_".$file;
open(FILE,$file) or die "cannot open $!";
my @lines=;
close(FILE);
foreach(@lines){
    my $user=(split(////,$_))[3];
    open TMP,">>./tmpfile" or die "cannot opent $!";
    print TMP $user."/n";
    close (TMP);
    }
system("sort -u ./tmpfile > ./tmpfile2");
open (FILE,"./tmpfile2") or die "cannot open $!";
my @users=;
close (FILE);
system("rm -f ./tmpfile ./tmpfile2");
foreach my $name(@users){
    chomp($name);
    my %tmp;
    foreach my $line(@lines){
        chomp($line);
        if($line=~///$name///){
            my $size=(split(/###/,$line))[1];
            if($line=~/(rmvb|dat|mpeg|mpg|wmv|rm|avi)$/){
                $tmp{video}+=$size;
                }
            elsif($line =~/(jpeg|jpg|gif|png)$/){
                $tmp{photo}+=$size;
                }
            elsif($line =~/mp3$/){
                $tmp{mp3}+=$size;
                }
            elsif($size>1000000000){
                $tmp{bigfile}+=$size;
                }
            }
        }
    open FH,">>./$to_file" or die "cannot open $!";
    print FH $name."/n";
    foreach my $obj(keys(%tmp)){
        my $total_size=&modi_size($tmp{$obj});
        print FH "   ".$obj." ".":"." ".$total_size."/n";
        }
}

sub modi_size{
my $size=shift;
if(($size>1000) && ($size<1000000)){
    $size=$size/1000;
    $size=~s/(/d+/./d)/d+/$1/;
    $size.="K";
    }
elsif(($size>=1000000) &&($size<1000000000)){
    $size=$size/1000000;
    $size=~s/(/d+/./d)/d+/$1/;
    $size.="M";
    }
elsif($size>=1000000000){
    $size=$size/1000000000;
    $size=~s/(/d+/./d)/d+/$1/;
    $size.="G";
    }
   
return $size;
}


生成最后的统计文件内容格式如下:
user1
   mp3 : 49.4M
   video : 337.7M
   photo : 1.0G
user2
   video : 3.5G
   photo : 4.8M
user3
   photo : 7.0M

total  : 98G
  


此处之所以分成两步,因为中间生成的那个文件还有它用,如果需要,很容易将两段代码合并。


转载请注明作者、出处!
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值