2012-01-18 57 views
1

發生了什麼事:檢查重複數組

我ssh'd到我的本地主機上,ls桌面和採取這些項目,並把它們放入一個數組。

我硬編碼了一個項目的短列表,我將它們與一個散列進行比較,以查看是否有東西從主機中丟失(查看某個東西是否不在b中,並讓我知道)。

所以在弄清楚之後,當我打印出「丟失的文件」時,我得到了一堆重複項(見下文),不確定這是否與循環中的文件檢查有關,但是我認爲要做的最好的事情就是整理數據並消除愚蠢。

當我這樣做,並打印出固定數據,只有一個文件正在打印,兩個丟失。

任何想法爲什麼?

#!/usr/bin/perl 

my $hostname = $ARGV[0]; 

my @hostFiles = ("filecheck.pl", "hostscript.pl", "awesomeness.txt"); 
my @output =`ssh $hostname "cd Desktop; ls -a"`; 

my %comparison; 
for my $file (@hostFiles) { 
    $comparison{$file} +=1; 
} 

for my $file (@output) { 
    $comparison{$file} +=2 
} 

for my $file (sort keys %comparison) { 
    @missing = "$file\n" if $comparison{$file} ==1; 
    #print "Extra file: $file\n" if $comparison{$file} ==2; 
    print @missing; 
} 

my @checkedMissingFiles; 

foreach my $var (@missing){ 
    if (! grep(/$var/, @checkedMissingFiles)){ 
     push(@checkedMissingFiles, $var); 
    } 
} 
print "\n\nThe missing Files without dups:\n @checkedMissingFiles\n"; 

密碼:

awesomeness.txt ##This is what is printing after comparing the two arrays 
awesomeness.txt 
filecheck.pl 
filecheck.pl 
filecheck.pl 
hostscript.pl 
hostscript.pl 

The missing Files without dups: ##淘汰後所打印複製 hostscript.pl

回答

2

這樣做將是Perl的方式:

#!/usr/bin/perl -w 

use strict; 
use Data::Dumper; 
my %hostFiles = qw(filecheck.pl 1 hostscript.pl 1 awesomeness.txt 1); 
# ssh + backticks + ls, not the greatest way to do this, but that's another Q 
my @files =`ssh $ARGV[0] "ls -a ~/Desktop"`; 
# get rid of the newlines 
chomp @files; 
#grep returns the matching element of @files 
my %existing = map { $_ => 1} grep {exists($hostFiles{$_})} @files; 
print Dumper([grep { !exists($existing{$_})} keys %hostFiles]); 

數據::翻車機是一種實用工具模塊,我用它來調試或示範的目的。

如果你想打印的清單,你可以做這樣的事情:

{ 
    use English; 
    local $OFS = "\n"; 
    local $ORS = "\n"; 
    print grep { !exists($existing{$_})} keys %hostFiles; 
} 

$ ORS是輸出記錄分隔符(它的任何打印之後打印)和$ OFS是印之間的輸出字段分隔符打印參數。請參閱perlvar。你可以逃避不使用「英語」,但變量名稱看起來更醜。塊和本地是這樣,你不必保存和恢復特殊變量的值。

如果要寫入文件的結果像這樣的事:

{ 
    use English; 
    local $OFS = "\n"; 
    local $ORS = "\n"; 
    open F, ">host_$ARGV[0].log"; 
    print F grep { !exists($existing{$_})} keys %hostFiles; 
    close F; 
} 

當然,你也可以做到這一點的「經典」的方式,循環槽數組並打印每個元素:

open F, ">host_$ARGV[0].log"; 
for my $missing_file (grep { !exists($existing{$_})} keys %hostFiles) { 
    use English; 
    local $ORS = "\n"; 
    print F "File is missing: $missing_file" 
} 
close F; 

這使您可以使用文件名做更多的事情,例如,您可以將SCP傳遞給主機。

+0

我認爲我最大的問題是將主機上的文件與上面的列表進行比較。我不想返回匹配元素,而是查找%hostFiles中的哪些不在@files中。 – jackie 2012-01-18 18:20:33

+0

我的不好,我錯過了。編輯。 – Sorin 2012-01-18 18:29:51

+1

啊。我正在閱讀Data :: Dumper文檔,看看它還能做些什麼......如果我不想「打印」這些數據,而是將它寫入文件或通過電子郵件發送信息,該怎麼辦? – jackie 2012-01-18 18:59:54

-1

@missing = 「$文件\ N」 給數組@missing包含一個單個元素「$ file \ n」。它在每個循環中執行此操作,並保留最後丟失的文件。

你想要的是推送(@missing,「$ file \ n」)。

1

在我看來,循環遍歷'required'列表更有意義 - 循環遍歷現有文件的列表是不必要的,除非您正在查找存在但不需要的文件。

#!/usr/bin/perl 
use strict; 
use warnings; 
my @hostFiles = ("filecheck.pl", "hostscript.pl", "awesomeness.txt"); 
my @output =`ssh $ARGV[0] "cd Desktop; ls -a"`; 
chomp @output; 
my @missingFiles; 
foreach (@hostFiles) { 
    push(@missingFiles, $_) unless $_ ~~ @output; 
} 
print join("\n", "Missing files: ", @missingFiles);