2009-10-30 27 views
0

我試圖找到具有相同名稱的文件並刪除所有較小尺寸的副本,只留下最大的副本。例如:test.jpg = 2kb,test.jpg = 9kb,test.jpg = 5kb。 2kb和5kb的文件將被刪除,只留下9kb。我已經嘗試了幾個GUI程序來做到這一點,他們沒有幫助,因爲你找到了副本後不得不手動刪除所有東西(當有大約400000個傻瓜時不太好)!是否有腳本可以這是否有人知道?刪除較小尺寸的文件副本

回答

0

此perl腳本查找當前目錄中的所有文件。然後將它們放入一個散列,其中文件的基本名稱是鍵,值是一個(大小,全路徑)對。然後它遍歷基本名稱,對重複進行排序並刪除除最大的那個之外的所有。

實際/ bin/rm被註釋掉。在你真正做到這一點之前,確保它做到了你想要的。

真正的perl黑客:如果我在這裏做一些天真愚蠢的事情,我很樂意瞭解這一點。

#!/usr/bin/perl -w 
use File::Basename; 
use strict; 

my @files = `/usr/bin/find -type f`; 
my %stats; 

# each hash key is the simple basename of the files 
# each hash value is a 2 element array of (size, fullpath) 
foreach my $file (@files) 
{ 
    chomp($file); 
    my $result = `/bin/ls -s $file`; 
    chomp($result); 
    if($result =~ /^(\d+)\s+(.*)/) 
    { 
     my ($basefile, $dir, $suffix) = fileparse($file); 
     push(@{$stats{$basefile}}, [$1, $2]); 
    } 
    else 
    { 
     printf STDERR "Unexpected ls output: $result\n"; 
    } 
} 

foreach my $file (keys %stats) 
{ 
    # sort from smallest to largest 
    my @sorted = sort {$b->[0] <=> $a->[0]} @{$stats{$file}}; 

    # remove the biggest one 
    pop(@sorted); 

    # for each one that's left remove it (use at your own risk!) 
    foreach my $path (@sorted) 
    { 
     # system("/bin/rm $path"); 
     printf "/bin/rm $path->[1]\n"; 
    } 
} 
1

這會查找所有文件並打印它們的名稱,大小和帶路徑名稱。然後按名稱對它們進行排序,然後按大小(降序)然後按路徑排序。 awk腳本會通過除第一個(最大)之外的所有腳本,並將其交給echo(刪除echo以使rm採取行動)。這應該對名稱中包含空格的文件起作用,但不適用於名稱中包含換行符或製表符的文件。

find -type f -printf "%f\t%s\t%p\n" | 
    sort -t $'\t' -k 1,1 -k 2,2rn -k 3,3 | 
    awk -F'\t' '{if ($1 == prevfile) printf "%s\0", $3; prevfile = $1}' | 
    xargs -0 -I{} echo rm \{\} 

在這個目錄結構(由tree -s生產),所有名爲「文件」將被除test/dir/dir/file刪除其在50個字節的最大。

test 
|-- [ 26] file 
|-- [ 4096] dir 
| |-- [ 34] file 
`-- [ 4096] dir 
    |-- [ 4096] dir 
    | |-- [ 50] file 
    `-- [ 4096] test 
     `-- [ 4096] dir 
      `-- [ 20] file 
+0

我們確實需要添加--head/- tail或等價的排序。這將是功能上和算法上有益 – pixelbeat 2009-10-30 10:55:40

+0

是的,我想我同意。它已經具有獨特的'-u',所以它看起來很合適。 – 2009-10-30 12:20:55