2012-06-28 202 views
0

我想查看名爲missing的文件,然後查看名爲flags的目錄。檢查目錄並與文件匹配

missing中列出的每個文件將始終出現在flags目錄中。

我想查看flags目錄中的每個文件,然後查看它們是否在missing文件中。如果其中一個不是,請從flags目錄中刪除該文件。

@flags=`ls $dir`; 
    $flags_size = scalar @flags; 

    $file = "/home1/t01jkxj/check_st/missing"; 
    $filesize = -s $file; 

    if ($filesize < $flags_size) { 
     ##What to do??## 
    } 
+0

爲什麼要將'$ file'的大小與'@ flags'數組中的元素數進行比較? – TLP

+0

@TLP:我認爲你很清楚OP不理解'-s'運算符。 – Borodin

+0

所以你想刪除名爲'flags'的目錄中的所有文件,這些文件不會出現在名爲'missing'的文件中? – Borodin

回答

0

檢查散列。將所有缺少的條目放入散列中。然後遍歷標誌目錄中的所有文件並檢查它是否在散列中。如果是,很好,如果沒有,刪除文件。

my %missings = map { chomp; $_ => 1 } do { 
    open my $fh, '<', $missing_file or die "Can't read $missing_file: $!"; 
    <$fh> 
}; 

opendir my $dh, $dir or die "Can't read from $dir: $!"; 
while(readdir $dh) { 
    unlink $_ unless delete $missings{$_}; 
} 

# I know, you said this can't happen. 
if (keys %missings) { 
    print "The following are in $missing_file but not in $dir:\n"; 
    print " $_\n" for sort keys %missings; 
} 

警告:完全未經測試。我在網頁瀏覽器中輸入了這個框。

+0

您的警告是有保證的。你的代碼將試圖解除鏈接'.'和'..'(但它有可能失敗,因爲unlink通常不能刪除目錄),並且在錯誤的目錄中。 – TLP

0

現在不在Linux中,但這是您需要做的事情。該腳本收集文件和陣列目錄中的文件列表,然後找出兩者的區別。我會測試,但不能真的) - =。考慮它僞代碼!:

use strict; 
use warnings; 
my $fi; 
my $line; 
my @to_delete; 
my $var; 
my @indir; 
my @files; 
# the difference of @females and @simpsons 
@indir = `ls`; 

open($fi, "< list.txt"); 
while ($line = <$fi>) 
{ 
    chomp($line); 
    push @files, $line; 
} 
@to_delete=grep(!defined $indir{$_}, @files); #gets difference of the two arrays 


print "Delete this:\t$_\n" foreach (@to_delete); 
+0

你不能像這樣使用chomp:'push @files,chomp($ line)'。 'chomp'返回從參數中移除的字符總數,而不是參數本身。而且,你不能像這樣grep,因爲你在'%flags'哈希中沒有任何鍵。 – TLP

+0

謝謝 - 這些都是我的巨大錯誤。讓我認識其他人。或者只是編輯它是正確的,因爲我可能會花太多的草稿。 – PinkElephantsOnParade

0

在我看來,你可以用bash命令來做到這一點。例如:

cd /path/to/flags; ls | grep -vf missing.txt | xargs rm 

注意:請不要在沒有測試的情況下運行上述操作。

在perl中,在代碼中稍微詳細一點併發出警告可能是一個好主意。當然,這些警告可以被移除以用於自動化作業。

use strict; 
use warnings; 

my $dir = "/path/to/flags"; 
chdir $dir or die $!;  # change working directory 
my @flags = <*>;    # get a list of the files 
my $file = "/home1/t01jkxj/check_st/missing"; 
open my $fh, "<", $file or die $!; 
chomp(my @missing = <$fh>); # get file names and remove newlines 
my %missing = map { $_ => 1 } @missing; # ..and put them in a hash 

my @delete; 
for my $file (@flags) {  # all files not in the hash go into @delete 
    push @delete, $file unless $missing{$file}; 
} 

if (@delete) { # do not delete without confirmation 
    print @delete . " files to delete\[email protected]\n---\nDelete them all? "; 
    my $reply = <>; 
    if ($reply =~ /^y$/) { 
     unlink $_ or warn "$_: $!" for @delete; 
    } 
} else { 
    print "No missing files to delete.\n"; 
} 
1

你不描繪這一missing文件的格式,但我想它每行包含一個文件中並賦予該文件的完整絕對路徑。如果我猜錯了,你需要調整這個解決方案。

該程序將missing文件加載到散列中。每個散列元素都有文件名作爲其鍵值,值爲1.

打開flags目錄,並將路徑添加到每個文件名中以形成$filename中的絕對路徑。如果它沒有出現在%missing散列中,則會打印該文件名。要實際刪除該文件,unlink行應該被取消註釋。

use strict; 
use warnings; 

my $missing = "/home1/t01jkxj/check_st/missing"; 

open my $fh, '<', $missing or die qq(Unable to open "$missing" for read: $!); 
my %missing; 
while (<$fh>) { 
    next unless /\S/; 
    chomp; 
    $missing{$_} = 1; 
} 

my $dir = '/path/to/flags'; 

opendir my $dh, $dir or die qq(Unable to open directory "$dir": $!); 

for my $file (readdir $dh) { 
    my $filename = "$dir/$file"; 
    unless ($missing{$filename}) { 
    # unlink $filename; 
    print qq(File "$filename" deleted as not found in 'missing' file\n); 
    } 
} 
相關問題