Проверка на наличие дубликатов в массиве - PullRequest
1 голос
/ 18 января 2012

Что происходит:

Я отправил ssh'd на свой локальный хост, ls рабочий стол, взял эти элементы и поместил их в массив.

Я жестко запрограммировал короткий список элементов и сравнил их с хешем, чтобы увидеть, отсутствует ли что-либо на хосте (посмотрите, нет ли чего-то из a в 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

Ответы [ 3 ]

2 голосов
/ 18 января 2012

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]);

Data :: Dumper - это служебный модуль, я использую его для отладки или в демонстрационных целях.

Если вы хотите напечататьВ списке вы можете сделать что-то вроде этого:

{
    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;

Это позволяет вам делать больше вещей с именем файла, например, вы можете переадресовать его на хост.

1 голос
/ 19 января 2012

Мне кажется, что циклический просмотр списка «обязательных» имеет больше смысла - циклический просмотр списка существующих файлов не требуется, если вы не ищете файлы, которые существуют, но не нужны.*

0 голосов
/ 18 января 2012

@ missing = "$ file \ n" назначает массив @missing, содержащий один элемент, "$ file \ n". Он делает это каждый цикл, оставляя его с последним отсутствующим файлом.

То, что вы хотите - это push (@missing, "$ file \ n").

...