我想创建一个包含某些对象的配置文件,如此(当然,没有一个参数可以被视为主键)
param1=abc
param2=ghj
param1=bcd
param2=hjk
; always the sames parameters
这个文件可以被读取,让我们说Config::IniFiles
,因为它有直接转录到ini文件,就像这样
[0]
param1=abc
param2=ghj
[1]
param1=bcd
param2=hjk
,例如
之类的东西perl -pe 'if (m/^\s*$/ || !$section ) print "[", ($section++ || 0) , "]"'
以
结束open my $fh, '<', "/path/to/config_file.ini" or die $!;
$cfg = Config::IniFiles->new( -file => $fh );
(...parse here the sections starting with 0.)
但是,我在这里问了一些关于事情变得相当复杂的问题......
(A)有没有办法转换$ fh,以便在顺序读取文件之前不需要执行perl单行程序?因此,在perl期间转换文件实际上是在阅读它。
或
(B)是否有一个模块可以阅读我的精彩数据库?或者是什么东西?我让myslef说,Gnu coreutils会做这种平面文件阅读,但我不记得是怎么做的。
答案 0 :(得分:1)
您可以使用变量引用而不是文件名来创建从中读取的文件句柄:
use strict;
use warnings;
use autodie;
my $config = "/path/to/config_file.ini";
my $content = do {
local $/;
open my $fh, "<", $config;
"\n". <$fh>;
};
# one liner replacement
my $section = 0;
$content =~ s/^\s*$/ "\n[". $section++ ."]" /mge;
open my $fh, '<', \$content;
my $cfg = Config::IniFiles->new( -file => $fh );
# ...
答案 1 :(得分:1)
您可以将修改后的数据存储在真实文件或字符串变量中,但我建议您通过设置输入记录分隔符 {{1}来使用段落模式到空字符串。喜欢这个
$/
<强>输出强>
use strict;
use warnings;
{
local $/ = ''; # Read file in "paragraphs"
my $section = 0;
while (<DATA>) {
printf "[%d]\n", $section++;
print;
}
}
__DATA__
param1=abc
param2=ghj
param1=bcd
param2=hjk
<强>更新强>
如果您将文件读入字符串,如上所述添加节标识符,则可以使用字符串引用将结果直接读入[0]
param1=abc
param2=ghj
[1]
param1=bcd
param2=hjk
对象,例如
Config::IniFiles
此示例显示 tie 接口,该接口生成包含配置信息的Perl哈希。我只使用my $config = Config::IniFiles->new(-file => \$modified_contents)
来显示结果哈希的结构。
Data::Dump
<强>输出强>
use strict;
use warnings;
use Config::IniFiles;
my $config;
{
open my $fh, '<', 'config_file.ini' or die "Couldn't open config file: $!";
my $section = 0;
local $/ = '';
while (<$fh>) {
$config .= sprintf "[%d]\n", $section++;
$config .= $_;
}
};
tie my %config, 'Config::IniFiles', -file => \$config;
use Data::Dump;
dd \%config;
答案 2 :(得分:1)
您可以创建Config::INI::Reader的简单子类:
package MyReader;
use strict;
use warnings;
use base 'Config::INI::Reader';
sub new {
my $class = shift;
my $self = $class->SUPER::new( @_ );
$self->{section} = 0;
return $self;
}
sub starting_section { 0 };
sub can_ignore { 0 };
sub parse_section_header {
my ( $self, $line ) = @_;
return $line =~ /^\s*$/ ? ++$self->{section} : undef ;
}
1;
根据您的输入,这会给出:
% perl -MMyReader -MData::Dumper -e 'print Dumper( MyReader->read_file("cfg") )'
$VAR1 = {
'1' => {
'param2' => 'hjk',
'param1' => 'bcd'
},
'0' => {
'param2' => 'ghj',
'param1' => 'abc'
}
};
答案 3 :(得分:0)
您可能希望对一系列对象(如Powershell)执行操作,而不是文本流,因此
use strict;
use warnings;
use English;
sub operation {
# do something with objects
...
}
{
local $INPUT_RECORD_SEPARATOR = '';
# object are separated with empty lines
while (<STDIN>) {
# key value
my %object = ( m/^ ([^=]+) = ([[:print:]]*) $ /xmsg );
# key cannot have = included, which is the delimiter
# value are printable characters (one line only)
operation ( \%object )
}
也像其他答案一样。