Perl сортирует массив из нескольких столбцов - PullRequest
1 голос
/ 13 января 2012

Файл hostlist.txt содержит только 1 столбец. Прога читает файл hostlist.txt, удаляет повторяющиеся имена хостов, сортирует список, ищет ip-адрес каждого хоста в списке и печатает вывод на терминале.

hostlist.txt

host01
host03
host02
host01

вывод на клемму

host01,192.168.1.15
host02,192.168.1.12
host03,192.168.1.33

Программа:

open(HOSTFILE, "hostlist.txt") or die "Couldn't open location file: $!\n";
while ($hosts = <HOSTFILE>) {
    chomp($hosts);
    push(@hostnames, $hosts);
}
close HOSTFILE;
@hostnameUnique = uniq(@hostnames);
@hostnameUniqueSorted = sort { lc($a) cmp lc($b) } @hostnameUnique; 

foreach $hostname (@hostnameUniqueSorted){
    $ipaddr = inet_ntoa((gethostbyname($hostname))[4]);
    print "$hostname,$ipaddr\n";
}

Я хочу сделать то же самое, что и выше, за исключением того, что входной файл newhostlist.txt имеет 3 столбца. Удалите повторяющееся имя хоста, отсортируйте сначала столбец ($type), затем сортируйте 3-й столбец ($location), затем сортируйте 2-й столбец ($hostname), найдите ip-адрес и напечатайте вывод.
Как мне обработать массив из нескольких столбцов?

newhostlist.txt

dell,host01,dc2
dell,host03,dc1
hp,host02,dc1
dell,host01,dc2

Вывод:

dell,host03,192.168.1.33,dc1
hp,host02,192.168.1.12,dc1
dell,host01,192.168.1.15,dc2

Ответы [ 3 ]

3 голосов
/ 13 января 2012
#!/usr/bin/perl
use strict;
use warnings;

open(my $fh, '<', "newhostlist.txt") or die "Unable to open file: $!\n";

my %unique = map {$_ => 1} <$fh>;

my @data = 
    map {join",", ($_->[0], $_->[1], (@{$_->[3]}=gethostbyname($_->[1]))?inet_ntoa($_->[3][4]):'-' , $_->[2])}
    sort {$a->[0] cmp $b->[0] ||
          $a->[2] cmp $b->[2] ||
          $a->[1] cmp $b->[1]}
    map {s/^\s+|\s+$//g; [split/,/]} keys %unique;
3 голосов
/ 13 января 2012

ETA: Добавлена ​​проверка на неудачный поиск ipaddr.

Самый простой способ справиться с этим - использовать оператор diamond, я чувствую:* Использование ARGV :: readonly позволяет несколько безопаснее использовать неявные открытия файлов, используемые с оператором diamond.

После этого просто отсеките строки, уже просмотренные с использованием хеша, разбейте строку, введите нужное вам значение там, где вам это нужно, и распечатайте повторно собранную строку.ожидая более сложных данных в ваших строках, вы можете захотеть взглянуть на модуль csv, например Text :: CSV .

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

Я рекомендую использовать для этого массив хэшей:

.....
my ($type, $hostname, $location) = split /,/, $line;
push @records, {
    type => $type,
    hostname => $hostname,
    location => $location,
};
.....

my @records_sorted = sort { $a->{type} cmp $b->{type} || $a->{location} cmp $b->{location} || $a->{hostname} cmp $b->{hostname} } @records;
...
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...