Perl 从文件读取到散列

Perl reading from file into 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))

我想说 Port 作为密钥,包含密钥:111538452263125。我将如何着手将此文件读入我概述的结构中的哈希?

如果您的数据是制表符分隔的,正如您在上面的评论中提到的,您可以使用 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
}

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

我将为您提供 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))

如果您愿意,您可以采用'named field'方法,但如果您的数据格式是一致的,则没有太大关系。请记住,您的数据实际上看起来不像是制表符分隔的 - 如果不是,则拆分空格会更容易......但它也会在 Peer Addr 上变为 'break'。

如果你想走那条路,你需要查看 slice 的散列。但是,这不会起作用,因为您有一个没有 header 行的字段,如果这样做,它可能会被丢弃。

例如:

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