先介绍一下写此脚本的背景,我们使用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
此处之所以分成两步,因为中间生成的那个文件还有它用,如果需要,很容易将两段代码合并。
转载请注明作者、出处!
脚本分成两部分,第一查找出指定目录下所指定查找类型的文件(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
此处之所以分成两步,因为中间生成的那个文件还有它用,如果需要,很容易将两段代码合并。
转载请注明作者、出处!