2015-04-28 4 views
-1

Я хотел бы прочитать содержимое файла в хэш-структуре. Заголовок файла должен быть ключом в структуре хеша, а также значениями, являющимися содержимым, указанным ниже каждого столбца.Perl чтение из файла в хэш

Файл, который я собираюсь прочитать, будет выглядеть примерно так.

Recv-Q Send-Q    Local Address:Port    Peer Address:Port 
0  128       *:111       *:*  users:(("rpcbind",1268,8)) 
0  128       *:53845       *:*  users:(("rpc.statd",1404,9)) 
0  128       *:22       *:*  users:(("sshd",1577,3)) 
0  128     127.0.0.1:631       *:*  users:(("cupsd",1452,7)) 
0  100     127.0.0.1:25       *:*  users:(("master",1686,12)) 

Я хотел бы иметь скажем порт как ключ, содержащий ключи: , , , , . Как бы я пошел, чтобы прочитать этот файл в хеше в структуре, которую я изложил?

+5

Что вы пробовали? –

+2

Вам нужно определить, как линии будут разделены на поля. Просто пробелы? Колоны? Фиксированные позиции? Затем вам нужно прочитать первую запись и разбить ее на массив строк. Наконец, вы читаете все остальные записи, разбивая каждый на массив значений и назначая их хэш-значениям - на основе ключей, которые вы читаете в массиве из первой строки файла. –

+0

Я действительно не знаю, как добиться успеха в этой задаче. Я только запрограммировал более простые задачи, читающие из файлов, ряд за строкой. Я не знаю, как сделать программу осведомленной о том, что я хочу использовать заголовки первой строки в качестве ключей. Я знаю, что я должен использовать «вкладку» в качестве разделителя. – user3691006

ответ

2

Я предлагаю вам базовый стартер для 10 о том, как анализировать данные.

#!/usr/bin/env perl 

use strict; 
use warnings; 
use Data::Dumper; 
my @header = split (" ", <DATA>); 

my %service_on; 


while (<DATA>) { 
    my ($recvq, $sendq, $locaddr_port, $peeraddr_port, $thing) = split; 
    my ($locaddr, $port) = split (":", $locaddr_port); 
    $service_on{$port} = $thing; 
} 

print Dumper \%service_on; 


__DATA__ 
Recv-Q Send-Q    Local Address:Port    Peer Address:Port 
0  128       *:111       *:*  users:(("rpcbind",1268,8)) 
0  128       *:53845       *:*  users:(("rpc.statd",1404,9)) 
0  128       *:22       *:*  users:(("sshd",1577,3)) 
0  128     127.0.0.1:631       *:*  users:(("cupsd",1452,7)) 
0  100     127.0.0.1:25       *:*  users:(("master",1686,12)) 

Вы можете сделать «имени поля» подход, если вы хотите, но если ваш формат данных соответствует, это не имеет значения слишком много. Имейте в виду, что ваши данные на самом деле не выглядят так, как будто они ограничены табуляцией - если это не так, расщепление по пробелу проще ... но оно также будет «ломаться» на Peer Addr.

Если вы хотите спуститься по этой дороге, вам нужно посмотреть slice s хеша. Однако это не сработает, поскольку у вас есть поле без строки заголовка, которое можно просто отбросить, если вы это сделаете.

т.д .:

while (<DATA>) { 
    my %fields; 
    @fields{@header} = split; 
    my ($locaddr, $port) = split (":", $fields{$port_field}); 
    print Dumper \%fields; 
} 
2

Если ваши данные разделены табуляцией, как вы отметили в комментарии выше, вы можете использовать функцию split для разделения строки (например, строки из файла) на массив значений. В большинстве систем, если perl установлен правильно, вы можете посмотреть документацию этой функции с помощью команды perldoc -f split.

# Read the first line of the file: 
my $header = <$fh>; 
chomp $header; 
my @fields = split /\t/, $header; 
# 
# Then read the rest of the lines: 
my %data; 
while (my $line = <$fh>) 
{ 
    my @values = split /\t/, $line; 
    @data{@fields} = @values; 
    ... # do something with %data here 
} 

Если данные ограничен какой-то другой путь, вы должны изменить, как вы разделить каждую строку на поля.

Смежные вопросы