当前位置: 技术问答>linux和unix
哪位高手能帮忙把以下代码改为shell或者实现该功能也行
来源: 互联网 发布时间:2016-08-29
本文导语: 先介绍一下写此脚本的背景,我们使用samba共享,每个人都有自己的个人目录,和群组共用目录,现在发现磁盘空间消耗的很厉害,上服务查一下才发现在,好多人在个人目录下放了好多mp3,图片,视频之类的文件,为...
先介绍一下写此脚本的背景,我们使用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=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
此处之所以分成两步,因为中间生成的那个文件还有它用,如果需要,很容易将两段代码合并。
本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/solarium/archive/2008/12/22/3581398.aspx
脚本分成两部分,第一查找出指定目录下所指定查找类型的文件(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=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
此处之所以分成两步,因为中间生成的那个文件还有它用,如果需要,很容易将两段代码合并。
本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/solarium/archive/2008/12/22/3581398.aspx
|
#!/bin/sh
# 指定目录
WORK_DIR=
# 统计
RESLT_FILE=
# step 1
for file_type in mp3 jpeg etc
do
# 打印出大小,文件名,文件路径
find ${WORK_DIR} -name "*.${file_type}" | xargs ls -l | awk '{
arr_size=split($9,arr,"/");
print $5,arr[arr_size],$9
}' | awk 'sub("/"$2,"",$3){print $1,$2,$3}' > ${RESLT_FILE}
done
# step 2
awk '{a[$3" "$2]+=$1;a[$3" "$2]++}END{for (i in a) print i,a[i]}' ${RESLT_FILE}
# 指定目录
WORK_DIR=
# 统计
RESLT_FILE=
# step 1
for file_type in mp3 jpeg etc
do
# 打印出大小,文件名,文件路径
find ${WORK_DIR} -name "*.${file_type}" | xargs ls -l | awk '{
arr_size=split($9,arr,"/");
print $5,arr[arr_size],$9
}' | awk 'sub("/"$2,"",$3){print $1,$2,$3}' > ${RESLT_FILE}
done
# step 2
awk '{a[$3" "$2]+=$1;a[$3" "$2]++}END{for (i in a) print i,a[i]}' ${RESLT_FILE}