如何在文件中组合两行然后对其进行排序

时间:2014-03-20 20:27:09

标签: perl

我是perl的新手,请帮助,我有一个带日期的文本文件:

id      period   value  date
=============================
SEC A   -0.07   19831117
SEC A   -0.07   19831215
SEC Q   0.07    0
SEC A   0.01    0
SEC Q   -0.17   0
SEC Q   0.01    0
SEC Q   0.66    0
SEC A   -0.52   19860417
SEC A   -0.52   19860619
SEC A   -0.52   19860717
SEC A   -0.52   19860814
SEC A   -0.52   19860918
SEC A   -0.52   19861016
SEC Q   -0.38   19860417
SEC A   -0.3    0
SEC Q   -0.01   19860619
SEC Q   -0.01   19860717
SEC Q   -0.01   19861016
SEC Q   -0.1    19861120

如果第二列中的字段A和Q具有相同的日期(第4列),我想根据按日期(第4列)分组的第2列(A / Q)组合两行,然后将这些行组合成一行,否则只打印日期不为零的数据:

输出文件如下所示:

id      date            Value (A)   Valaue(Q)
===========================================
SEC 19831117    -1.17   0
SEC 19831215    -1.17   0
SEC 19860116    -1.36   1.02
SEC 19860220    -1.36   1.02
SEC 19860320    -1.36   1.02
SEC 19860417    -1.52   -1.38
SEC 19860619    -1.52   -1.01
SEC 19860717    -1.52   -1.01
SEC 19861016    -1.52   -1.01

2 个答案:

答案 0 :(得分:1)

看起来您想要按日期键,因此您想要在日期创建记录。请注意,我将所有内容存储在记录中,这使其更易于扩展以用于其他目的。

my %hash;

foreach ( <lines> ) { 
    # split on whitespace
    my ( $id, $key, $value, $date ) = split ' ';
    # check for existing record to append to
    my $rec 
          = $hash{ $date } 
        # if this record is not found, it is initialized
        //= { id   => $id
            , date => $date
              # the following statement means *map* each string in ('A', 'Q')
              # to the default of 0
            , ( map { $_ => 0 } qw<A Q> ) 
            }
        ;
    # in both cases we want to set the value
    $hash{ $key } = $value;
}

foreach ( sort keys %hash ) { 
    my $rec = $hash{ $_ };
    say "$rec->{id}\t$_\t$rec->{A}\t$rec->{Q}";
}

答案 1 :(得分:0)

您可以有两个单独的哈希值,一个用于A,一个用于Q.哈希的键可以是日期,值是值。迭代输入以生成哈希值。

一旦有两个哈希值,迭代其中一个哈希值并尝试在具有相同日期的另一个哈希值中查找条目。将相关信息放入数组的哈希值,并按日期键入。伪代码(因为我无法完全记住perl语法):

%hashA = () ; # a hash of scalars 
%hashQ = () ; # a hash of scalars
%hashAQ = () ; # a hash of arrays of size two, element 1 is A's value, element 2 is Q's value

## TODO: Put code to read the input and populate the first two hashes above 

foreach($key in hashA) {
    if (exists $hashQ{$key}) { 
        $hashAQ{$key} = @($hashA{key}, $hashQ{key}) ; 
    }
}  

## TODO: sort hashAQ by the key (which is the date) and then print the values 

如果A(或Q)具有多个具有相同日期的值,则让哈希使用数组值而不是缩放器值。数组将包含相关日期的所有A(或Q)值。