首页 > 解决方案 > Perl 哈希:使用来自外部文本文件的键/值对

问题描述

我正在尝试创建一个哈希,该哈希从我服务器上的单独文本文件中提取其键/值对。

当我手动将键/值对输入到我的 perl 脚本中的散列中时,如下例所示,当我稍后调用它时,散列可以完美地工作:

# Initialize hash 
my %format_key = ('SGBK', 'PRINT', 'SGDVD', 'VIDEO');

# Call hash (this is much later in the program)
$item_format = $format_key{$fields[2]};

当我将这些完全相同的参数保存到文本文件中,然后读入该文件,将内容保存到标量变量,并将该变量分配给散列中的参数时,散列不起作用。这是我所做的:

# Open file path saved in $format_key_file and save contents to $output
open(my $fh, '<', $format_key_file) or die "Could not read from $format_key_file, program halting."; {
 local $/;
 $output = <$fh>;
 }
 close($fh);

my %format_key = $output;

 # Call hash (this is much later in the program)
    $item_format = $format_key{$fields[2]};

我完全被难住了。我想我可以手动将所有哈希参数输入到脚本本身中,但是会有很多这些参数,我希望将它们保存在一个文件中,以便于以后更新。

标签: fileperlhash

解决方案


当您从文件中读取时,您会得到一个字符串(或多个字符串,如果您逐行读取)。Perl 解析器只解析传递给 Perl 解释器的源代码,而不是您从文件或其他地方读取的任何内容。您可以使用eval函数将像这样的任意字符串评估为 perl 代码并返回最后一个表达式的结果(在本例中为字符串列表),但字符串 eval 很危险,因为它可以运行任何代码;如果您不小心读取了包含system 'rm -rf ~/*'您有问题的文件。

更好的选择是以已知的序列化格式存储数据。用于此类事情的常用格式是JSON,因为它巧妙地映射到 Perl 数据结构,但对于像这样的简单情况,您也可以将字符串存储为行(没有像引用这样的 Perl 语法)。还有许多其他选项,例如 YAML,甚至 XML,但它们更难解码;和二进制格式,如 Storable、Sereal 和 CBOR,但它们不是人类可读的,因此只能通过您的代码进行交互。

use strict;
use warnings;
use JSON::MaybeXS;
# if you store it as JSON: {"SGBK":"PRINT","SGDVD":"VIDEO"}
my %format_key = %{decode_json($output)};
# or from an even-sized array: ["SGBK","PRINT","SGDVD","VIDEO"]
my %format_key = @{decode_json($output)};

# if you store it as one value per line
my %format_key = split /\n/, $output;

推荐阅读