帮助将哈希键打印为所需的格式
我需要帮助将数据从哈希/哈希引用打印到 STDOUT 或文件 如果可能的话,按特定顺序排列数据。
我有一个使用哈希引用的 Perl 例程,如下所示:
#!/usr/local/bin/perl
use strict;
use warnings;
use File::Basename;
use Data::Dumper;
my %MyItems;
my $ARGV ="/var/logdir/server1.log";
my $mon = 'Aug';
my $day = '06';
my $year = '2010';
while (my $line = <>)
{
chomp $line;
if ($line =~ m/(.* $mon $day) \d{2}:\d{2}:\d{2} $year: ([^:]+):backup:/)
{
my $server = basename $ARGV, '.log';
my $BckupDate="$1 $year";
my $BckupSet =$2;
$MyItems{$server}{$BckupSet}->{'MyLogdate'} = $BckupDate;
$MyItems{$server}{$BckupSet}->{'MyDataset'} = $BckupSet;
$MyItems{$server}{$BckupSet}->{'MyHost'} = $server;
if ($line =~ m/(ERROR|backup-size|backup-time|backup-status)[:=](.+)/)
{
my $BckupKey=$1;
my $BckupVal=$2;
$MyItems{$server}{$BckupSet}->{$BckupKey} = $BckupVal;
}
}
}
foreach( values %MyItems ) {
print "MyHost=>$_->{MyHost};MyLogdate=>$_->{MyLogdate};MyDataset=>$_->{MyDataset};'backup-time'=>$_->{'backup-time'};'backup-status'=>$_->{'backup-status'}\n";
}
使用转储器输出:
$VAR1 = 'server1';
$VAR2 = {
'abc1.mil.mad' => {
'ERROR' => ' If you are sure is not running, please remove the file and restart ',
'MyLogdate' => 'Fri Aug 06 2010',
'MyHost' => 'server1',
'MyDataset' => 'abc1.mil.mad'
},
'abc2.cfl.mil.mad' => {
'backup-size' => '187.24 GB',
'MyLogdate' => 'Fri Aug 06 2010',
'MyHost' => 'server1',
'backup-status' => 'Backup succeeded',
'backup-time' => '01:54:27',
'MyDataset' => 'abc2.cfl.mil.mad'
},
'abc4.mad_lvm' => {
'backup-size' => '422.99 GB',
'MyLogdate' => 'Fri Aug 06 2010',
'MyHost' => 'server1',
'backup-status' => 'Backup succeeded',
'backup-time' => '04:48:50',
'MyDataset' => 'abc4.mad_lvm'
}
};
我希望看到的输出格式:
MyHost=>server1;MyLogdate=>Fri Aug 06 2010;MyDataset=>abc2.cfl.mil.mad;backup-time=>Fri Aug 06 2010;backup-status=>Backup succeeded
刚刚添加(2010 年 8 月 7 日): 我正在使用的示例原始日志文件:(最近添加以提供源日志的更好表示)
Fri Aug 06 00:00:05 2010: abc2.cfl.mil.mad:backup:INFO: backup-set=abc2.cfl.mil.mad
Fri Aug 06 00:00:05 2010: abc2.cfl.mil.mad:backup:INFO: backup-date=20100806000004
Fri Aug 06 00:48:54 2010: abc4.mad_lvm:backup:INFO: backup-size=422.99 GB
Fri Aug 06 00:48:54 2010: abc4.mad_lvm:backup:INFO: PHASE END: Calculating backup size & checksums
Fri Aug 06 00:48:54 2010: abc4.mad_lvm:backup:INFO: backup-time=04:48:50
Fri Aug 06 00:48:54 2010: abc4.mad_lvm:backup:INFO: backup-status=Backup succeeded
Fri Aug 06 00:48:54 2010: abc4.mad_lvm:backup:INFO: Backup succeeded
I need help printing out data from a hash/hash ref to STDOUT or file with
data in a specific order if possible.
I have a perl routine that uses hash references like so:
#!/usr/local/bin/perl
use strict;
use warnings;
use File::Basename;
use Data::Dumper;
my %MyItems;
my $ARGV ="/var/logdir/server1.log";
my $mon = 'Aug';
my $day = '06';
my $year = '2010';
while (my $line = <>)
{
chomp $line;
if ($line =~ m/(.* $mon $day) \d{2}:\d{2}:\d{2} $year: ([^:]+):backup:/)
{
my $server = basename $ARGV, '.log';
my $BckupDate="$1 $year";
my $BckupSet =$2;
$MyItems{$server}{$BckupSet}->{'MyLogdate'} = $BckupDate;
$MyItems{$server}{$BckupSet}->{'MyDataset'} = $BckupSet;
$MyItems{$server}{$BckupSet}->{'MyHost'} = $server;
if ($line =~ m/(ERROR|backup-size|backup-time|backup-status)[:=](.+)/)
{
my $BckupKey=$1;
my $BckupVal=$2;
$MyItems{$server}{$BckupSet}->{$BckupKey} = $BckupVal;
}
}
}
foreach( values %MyItems ) {
print "MyHost=>$_->{MyHost};MyLogdate=>$_->{MyLogdate};MyDataset=>$_->{MyDataset};'backup-time'=>$_->{'backup-time'};'backup-status'=>$_->{'backup-status'}\n";
}
Output using dumper:
$VAR1 = 'server1';
$VAR2 = {
'abc1.mil.mad' => {
'ERROR' => ' If you are sure is not running, please remove the file and restart ',
'MyLogdate' => 'Fri Aug 06 2010',
'MyHost' => 'server1',
'MyDataset' => 'abc1.mil.mad'
},
'abc2.cfl.mil.mad' => {
'backup-size' => '187.24 GB',
'MyLogdate' => 'Fri Aug 06 2010',
'MyHost' => 'server1',
'backup-status' => 'Backup succeeded',
'backup-time' => '01:54:27',
'MyDataset' => 'abc2.cfl.mil.mad'
},
'abc4.mad_lvm' => {
'backup-size' => '422.99 GB',
'MyLogdate' => 'Fri Aug 06 2010',
'MyHost' => 'server1',
'backup-status' => 'Backup succeeded',
'backup-time' => '04:48:50',
'MyDataset' => 'abc4.mad_lvm'
}
};
Output formatted that I would like to see:
MyHost=>server1;MyLogdate=>Fri Aug 06 2010;MyDataset=>abc2.cfl.mil.mad;backup-time=>Fri Aug 06 2010;backup-status=>Backup succeeded
Just addded (8/7/2010):
Sample raw log file I am using: (recently added to provide better representation of the source log)
Fri Aug 06 00:00:05 2010: abc2.cfl.mil.mad:backup:INFO: backup-set=abc2.cfl.mil.mad
Fri Aug 06 00:00:05 2010: abc2.cfl.mil.mad:backup:INFO: backup-date=20100806000004
Fri Aug 06 00:48:54 2010: abc4.mad_lvm:backup:INFO: backup-size=422.99 GB
Fri Aug 06 00:48:54 2010: abc4.mad_lvm:backup:INFO: PHASE END: Calculating backup size & checksums
Fri Aug 06 00:48:54 2010: abc4.mad_lvm:backup:INFO: backup-time=04:48:50
Fri Aug 06 00:48:54 2010: abc4.mad_lvm:backup:INFO: backup-status=Backup succeeded
Fri Aug 06 00:48:54 2010: abc4.mad_lvm:backup:INFO: Backup succeeded
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
我花了一些时间查看你的代码,我想我已经弄清楚了。
这个问题很难回答的原因是你无意中植入了一条转移注意力的信息——数据转储器的输出。
请注意它如何显示
$VAR1 = 'server1';
和$VAR2 = { blah };
。您可以这样调用 Dumper:
print Dumper %MyItems;
问题是 Dumper 想要转储一个值列表,因为 Perl 会展平列表,所以复杂的结构必须通过引用传递。因此,您需要像这样调用 Dumper:
这显示了整个结构。
当您之前调用 dumper 时,您无意中剥离了一层数据结构。建议的解决方案和您自己的代码正在这个剥离的结构上运行。
在这里,我添加了一些代码来处理额外的嵌套层(并使其与 Perl 5.8 兼容):
看起来您有很多问题,需要一些帮助来理解许多概念。我建议您在 Seekers of Perl Wisdom 中的 Perlmonks 上发布请求,以帮助改进您的代码。 SO 非常适合集中提问,但 PM 更适合代码返工。
** 原始答案:**
为了解决我无法复制的任何解析问题,我只是将
%MyItems
设置为您提供的 Dumper 的输出。您上面提到的警告与打印声明中所有复杂的引用和重复编码有关。我已将您的 print 语句替换为
map
以简化代码。天啊,你可能会想,一个大的连接地图并不简单。但实际上,它更简单,因为每个单独的表达单位都更小。什么更容易理解和正确?在正确且一致的庄园中,什么更容易更改和维护?
或
在这里,您只需更改传递给
map
的参数列表即可添加、删除或重新排列输出。对于其他样式,您需要进行大量复制/粘贴操作。我下面使用的映射有点复杂,因为它在打印值之前检查是否定义了给定的键,如果不存在则分配默认值。
I've spent some time looking at your code and I think I have it figured out.
The reason this was hard to answer is that you've unintentionally planted a red herring--the data dumper output.
Notice how it shows
$VAR1 = 'server1';
and then$VAR2 = { blah };
.You called Dumper like so:
print Dumper %MyItems;
The problem is that Dumper wants a list of values to dump, since Perl flattens lists, complex structures must be passed by reference. So, you need to call Dumper like so:
This shows the whole structure.
When you called dumper earlier, you inadvertently stripped off one layer of your data structure. The proposed solutions, and your own code are operating on this stripped structure.
Here I've bolted on some code to handle additional layer of nesting (and made it Perl 5.8 compatible):
It looks like you have a lot of questions and need some help getting your head around a number of concepts. I suggest that you post a request on Perlmonks in Seekers of Perl Wisdom for help improving your code. SO is great for focussed question, but PM is more amenable to code rework.
** Original answer: **
To get around any parsing issues that I can't replicate, I just set
%MyItems
to the output of Dumper you provided.Your warnings you mention above have to do with all the complicated quoting and repetitive coding you have in your print statement. I have replaced your print statement with a
map
to simplify the code.Holy crap, a big join map blah is not simpler, you might be thinking. But really, it is simpler because each individual unit of expression is smaller. What is easier to understand and get right? What is easier to alter and maintain in a correct and consistent manor?
or
Here, you can add, remove or rearrange your output merely by changing the list of arguments passed to
map
. With the other style, you've got a bunch of copy/paste to do.The map I use below is a bit more complex, in that it checks to see if a given key is defined before printing a value, and assign a default value if none is present.
未经测试,但理论上应该有效。这将为主 MyItems 哈希的每个键打印一个输出行。如果您希望将所有内容都放在一行上,则只需删除 \n 或添加一些其他分隔符即可。
Not tested but it should work in theory. This will print an output line for each of the keys for the main MyItems hash. If you want it all on one line you can just drop the \n or add some other separator.
不回答你问的问题,但这对我来说似乎不明智。
您需要一个散列数组而不是散列的散列。
哈希值没有排序,如果您希望它们排序,请使用数组。
Not answering the question you asked, but this doesn't seem sensible to me.
You want an array of hashes not a hash of hashes.
Hashes are not ordered, if you want them ordered then use an array.
感谢大家的帮助...
这对我有用。
Thanks everyone for pitching in their help...
This works for me.