从shell读取/转储perl哈希

时间:2017-11-11 00:27:27

标签: perl data-dumper perl-hash

我有一个只读的perl文件,其中定义了一个巨大的哈希值。反正我有没有读过这个perl文件并转出哈希内容?

这是文件中哈希的基本结构。

%hash_name = {
    -files => [
         '<some_path>',
    ],
    -dirs => [
         '<some_path>',
         '<some_path>',
         '<some_path>',
         '<some_path>',
         '<some_path>',
    ],
};

1 个答案:

答案 0 :(得分:2)

理想情况下,您要复制文件以便编辑它,然后将其转换为模块,以便很好地使用它。

但如果出于某种原因这是不可行的,这里有你的选择。

如果该哈希是文件中的唯一内容,请使用do “加载”并分配给哈希

use warnings;
use strict;

my $file = './read_this.pl';  # the file has *only* that one hash

my %hash = do $file;

这种do形式执行文件(将其作为脚本运行),返回最后计算的表达式。只有文件中的哈希表示最后一个表达式是哈希定义,正是您需要的。

如果哈希是未声明的,那么一个全局变量(或用our声明),然后在程序中声明为our一个具有相同名称的哈希值使用do

加载文件
our %hash_name;  # same name as in the file
do $file;        # file has "%hash" or "our %hash" (not "my %hash")

在这里,我们“选取”被评估为do的哈希以our

的优点运行文件

如果哈希是“词汇”,则声明为my %hash(应该是!)......好吧,这很糟糕。然后,您需要解析文件的文本,以便使用哈希提取行。这通常很难非常,因为它相当于解析Perl。 (哈希可以使用map构建,从作为引用或平面列表的子句返回...)一旦完成,你eval包含定义该哈希的文本的变量。

但是,如果你知道如何构建哈希,就像你暗示的那样,内部没有()

use warnings; 
use strict;

my $file = './read_this.pl';

my $content = do {  # "slurp" the file -- read it into a variable
    local $/;
    open my $fh, '<', $file or die "Can't open $file: $!";
    <$fh>;
};

my ($hash_text) = $content =~ /\%hash_name\s*=\s*(\(.*?\)/s;
my %hash = eval $hash_text;

这个简单的镜头遗漏了很多,假设哈希正如图所示。另请注意,这种eval形式存在严重的安全风险。

文件也使用require加载。除了它比do做得更多之外,重要的是,即使它多次运行require仍然只加载一次。这首先适用于模块,不应多次加载,而use确实使用require

另一方面,do每次都会这样做,是什么使它适合加载要用作数据的文件,大概每次都应该 。这是推荐的方法。请注意,require本身使用do来实际加载文件。

感谢Schwern发表评论。