Perl从文件读取到哈希

时间:2015-04-28 13:03:44

标签: perl hash

我想将文件的内容读入哈希结构。文件的标题应该是哈希结构中的键,以及值是每列下面列出的内容。

我要读的文件看起来像这样。

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

我想说端口作为键,包含键: 111 53845 22 631 25 。我将如何将此文件读入我概述的结构中的哈希值?

2 个答案:

答案 0 :(得分: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
}

如果您的数据以其他方式分隔,则您必须修改将每行划分为字段的方式。

答案 1 :(得分: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))

可以执行“命名字段”&#39;如果您愿意,可以采用这种方法,但如果您的数据格式一致,那么这并不重要。请记住,您的数据实际上看起来并不像它的制表符分隔 - 如果不是,则在空格上分割更容易......但它也会进入&#39 ;破&#39;在Peer Addr

如果你想走这条路,你需要查看散列的slice。但是,由于你有一个没有标题行的字段,这不会起作用,如果你这样做,可能会被丢弃。

E.g:

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