【问题标题】:Perl - compares array elements sentences with a variablePerl - 将数组元素句子与变量进行比较
【发布时间】:2012-10-18 04:30:13
【问题描述】:

我使用 grep 在temporaryF 文件和arrayWarning 之间返回不匹配的数组

my @c =grep!${{map{$_,1}@temporaryF}{$_},@arrayWarning;

@c 里面有很多行例如:

Sun Sep 30 00:05:55 fibre channel DENY forever
Sun Sep 30 00:06:55 fibre channel ROOT cause
Sun Sep 30 00:08:55 fibre channel ROOT cause 
Sun Sep 30 00:10:55 fibre channel ROOT cause  
Sun Sep 30 00:20:55 fibre channel DANN 
Sun Sep 30 00:30:55 fibre channel DANN  

如您所见,ROOT 在@c 中出现了 3 次。如何遍历@c 以仅输出最新出现的 ROOT -> Sun Sep 30 00:10:55 光纤通道 ROOT 而不是其他重复的行。

所以它会变成:

Sun Sep 30 00:05:55 fibre channel DENY forever  
Sun Sep 30 00:10:55 fibre channel ROOT cause  
Sun Sep 30 00:30:55 fibre channel DANN

【问题讨论】:

    标签: arrays perl grep


    【解决方案1】:

    注意:这是@RobEarl 答案的延伸——所以如果你喜欢它,请务必也给他点赞!

    这里的重点也是存储行数,以确保输出可以排序。

    加长版

    #!/usr/bin/perl
    
    use strict;
    use warnings;
    
    # store (with count)
    my $count  = 0;
    my %latest = map {
        my $source = (split /\s+/ => $_)[6];
        $source => {count => $count++, string => $_};
    } <DATA>;
    
    # output
    print $_->{string} for sort {$a->{count} <=> $b->{count}} values %latest;
    
    __DATA__
    Sun Sep 30 00:05:55 fibre channel DENY forever
    Sun Sep 30 00:06:55 fibre channel ROOT cause
    Sun Sep 30 00:08:55 fibre channel ROOT cause 
    Sun Sep 30 00:10:55 fibre channel ROOT cause  
    Sun Sep 30 00:20:55 fibre channel DANN 
    Sun Sep 30 00:30:55 fibre channel DANN  
    

    输出

    Sun Sep 30 00:05:55 fibre channel DENY forever
    Sun Sep 30 00:10:55 fibre channel ROOT cause  
    Sun Sep 30 00:30:55 fibre channel DANN  
    

    感觉有点像Schwartzian transform

    单行版本

    这是一个很好的例子,可以通过简单的 oneliner 和 perl 强大的interpreter switches 来完成任务:

    $ perl -nale '$l{$F[6]}={c=>$c++,s=>$_};END{print$_->{s}for sort{$a->{c}<=>$b->{c}}values%l}'
    Sun Sep 30 00:05:55 fibre channel DENY forever
    Sun Sep 30 00:06:55 fibre channel ROOT cause
    Sun Sep 30 00:08:55 fibre channel ROOT cause 
    Sun Sep 30 00:10:55 fibre channel ROOT cause  
    Sun Sep 30 00:20:55 fibre channel DANN 
    Sun Sep 30 00:30:55 fibre channel DANN  
    

    输出:

    Sun Sep 30 00:05:55 fibre channel DENY forever
    Sun Sep 30 00:10:55 fibre channel ROOT cause  
    Sun Sep 30 00:30:55 fibre channel DANN  
    

    【讨论】:

    • 您好,您能否发布一些有关您在代码中使用的__XYZ__ 语言结构的信息?它有一些名字,所以我可以搜索它吗?我以前从未见过。
    • 嗨@duri,我不确定这是否是最好的 perldoc 开始,但我在perldata 中找到了一些相关信息。这只是将程序及其输入数据存储在一个脚本文件中的一种便捷方式。 :)
    • 谢谢。抱歉跑题了。
    • 谢谢,这只有在警告词之后才有效 (split /\s+/ => $_)[6];但是如何将其更改为 substr($_,20)?我似乎无法在你的编码中工作。
    • @momokjaaaaa 请找到一种方法来显示您完整的无效代码! :)
    【解决方案2】:

    使用以 ROOT/DENY/DANN 为键的哈希:

    my %latest = map { (split(" "))[6] => $_ } @c;
    

    假设@c 按日期排序,values %latest 将包含:

    Sun Sep 30 00:10:55 fibre channel ROOT cause
    Sun Sep 30 00:05:55 fibre channel DENY forever
    Sun Sep 30 00:30:55 fibre channel DANN
    

    【讨论】:

    • @c 的顺序对values %latest 的顺序没有(已定义)影响,因为哈希没有顺序。
    • @memowe 不,但它确实会影响内容
    • 没关系,你是对的,例如只有 ROOT 的“最新”出现才能存活。但是,值列表并不像人们想象的那样按日期排序。
    • 我用可排序的输出添加了这个答案的扩展。
    • @memowe,看起来不错。我正在考虑从@c(最后是grep)获取订单,但通过哈希保留它可能更有意义。
    猜你喜欢
    • 2017-01-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-06-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多