Perl脚本|使用HASH [英] Perl Scripting | using HASHes
问题描述
我有一个如下所示的输入文件:
= IP1
abc [0]
abc [1]
abc [2]
= IP2
def [4]
def [8]
def [9]
$ c
$ b 我需要以下面的格式获得输出 - = IP1
abc [0-2]
= IP2
def [4,8-9]
我一直在尝试使用散列来实现上述目的,我读取文件的每一行,然后分割(用'[')每行,我保留第一部分作为关键字并再次读取该文件以将值保存在散列键的数组中。但我陷入了一个循环。任何人都可以提供如何实现上述的帮助?
好的,这是我的解决方案。如果没有任何关于传入数据的更好的信息,它可能比所需的更复杂。
它保留数据 - = IP
头文件和 xyz [9]
值的顺序与第一次遇到的顺序相同。我将数字范围缩小的代码分隔为子程序范围
这只是阅读将数据从文件中读入数据结构%data
和 @order
并再次打印出来。散列中的 @order
数组和 _order
子键用于保存遇到的值序列添加到每当一个新的密钥插入到相应的散列中
use strict;
使用警告;
my($ key,%data,@order); $(b
$ b while(<>){
chomp;
if(/ ^ = /){
$ key = $ _;
推送@order,$ key,除非$ data {$ key};
$ data {$ key} = {_order => []};
}
elsif(my($ key2,$ n)= /([^ \ [\] \s] +)\ [(\ d +)\] /){
my $ data = $ data {$ key};
push @ {$ data-> {_ order}},$ key2除非$ data-> {$ key2};
push @ {$ data-> {$ key2}},$ n;
为我的$ key(@order){
print $ key,\\\
;
my $ data = $ data {$ key};
$ b $ for my $ key2(@ {$ data-> {_ order}}){
printf%s [%s] \\\
,$ key2,ranges(sort { $ a< => $ b} @ {$ data-> {$ key2}});
}
}
子范围{
我的@ranges;
my($ start,$ end);
为我的$ n(@_){
if(未定义$ start){
$ start = $ end = $ n;
}
elsif($ n == $ end + 1){
$ end = $ n;
}
else {
push @ranges,$ start == $ end? $ start:$ start- $ end;
$ start = $ end = $ n;
}
}
push @ranges,$ start == $ end? $ start:$ start- $ end(如果已定义)$ start;
加入',',@ranges;
输出
= IP1
abc [0-2]
= IP2
def [4,8-9]
I have an input file which looks like below
=IP1
abc[0]
abc[1]
abc[2]
=IP2
def[4]
def[8]
def[9]
I need to get the output in the below format -
=IP1
abc[0-2]
=IP2
def[4,8-9]
I have been trying to achieve the above using hashes where I read each line of the file and then split(with'[') each line, I keep the first part as key and read the file again to keep the values in an array for the hash keys. But I am getting stuck in a loop. Can anyone provide help on how to achieve the above ?
Okay, here's my take on a solution. Without any better information on the incoming data it may be more complicated than necessary
It keeps the data -- both the =IP
headers and the xyz[9]
values in the same order that they are first encountered. I've separated out the generation of the number range contraction to subroutine ranges
It's simply a matter of reading the data in from the file -- which it expects as a parameter on the command line -- into data structures %data
and @order
and printing them out again. The @order
array and the _order
subkey of the hash are there to preserve the sequence that the values are encountered and are added to whenever a new key is inserted into the corresponding hash
use strict;
use warnings;
my ($key, %data, @order);
while ( <> ) {
chomp;
if ( /^=/ ) {
$key = $_;
push @order, $key unless $data{$key};
$data{$key} = { _order => [] };
}
elsif ( my ($key2, $n) = /([^\[\]\s]+)\[(\d+)\]/ ) {
my $data = $data{$key};
push @{ $data->{_order} }, $key2 unless $data->{$key2};
push @{ $data->{$key2} }, $n;
}
}
for my $key ( @order ) {
print $key, "\n";
my $data = $data{$key};
for my $key2 ( @{ $data->{_order} } ) {
printf "%s[%s]\n", $key2, ranges( sort { $a <=> $b } @{ $data->{$key2} } );
}
}
sub ranges {
my @ranges;
my ($start, $end);
for my $n ( @_ ) {
if ( not defined $start ) {
$start = $end = $n;
}
elsif ( $n == $end + 1 ) {
$end = $n;
}
else {
push @ranges, $start == $end ? $start : "$start-$end";
$start = $end = $n;
}
}
push @ranges, $start == $end ? $start : "$start-$end" if defined $start;
join ',', @ranges;
}
output
=IP1
abc[0-2]
=IP2
def[4,8-9]
这篇关于Perl脚本|使用HASH的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!