【问题标题】:Sorting by columns in perlperl中按列排序
【发布时间】:2015-12-29 20:20:57
【问题描述】:

我有一个名为 all_energy.out 的文件,我正在尝试以某种方式对其进行排序,以便我可以根据 all_energy.out 文件中的最低能量重新编号目录中的文件。所以我想创建一个数组,文件名和能量从最低能量开始,然后像名字和年龄一样增加能量。

类比示例:

Don 24
Jan 30
Sue 19

排序到

Sue 19
Don 24
Jan 30

all_energy.out 文件示例:最大负值是最低能量。

                                  Energy
0001_IP3_fullBinding_Rigid0001  -219.209742 
0001_IP3_fullBinding_Rigid0002  -219.188106
0001_IP3_fullBinding_Rigid0003  -219.064542
0001_IP3_fullBinding_Rigid0004  -219.050730
0001_IP3_fullBinding_Rigid0005  -219.044573
0001_IP3_fullBinding_Rigid0006  -218.927479
0001_IP3_fullBinding_Rigid0007  -218.919717
0001_IP3_fullBinding_Rigid0008  -218.900923
0001_IP3_fullBinding_Rigid0009  -218.898945
0001_IP3_fullBinding_Rigid0010  -218.889269
0001_IP3_fullBinding_Rigid0011  -218.871619
0001_IP3_fullBinding_Rigid0012  -218.859429
0001_IP3_fullBinding_Rigid0013  -218.848516
0001_IP3_fullBinding_Rigid0014  -218.835355
0001_IP3_fullBinding_Rigid0015  -218.822244
0001_IP3_fullBinding_Rigid0016  -218.819328
0001_IP3_fullBinding_Rigid0017  -218.818431
0001_IP3_fullBinding_Rigid0018  -218.815494
0001_IP3_fullBinding_Rigid0019  -218.798388
0001_IP3_fullBinding_Rigid0020  -218.792151
                                  Energy
0002_IP3_fullBinding_Rigid0001  -226.007998
0002_IP3_fullBinding_Rigid0002  -225.635657

文件名在能量值之前给出,例如 0001_IP3_fullBinding_Rigid0001.mol2 是第一个文件的名称。

示例解决方案:

0002_IP3_fullBinding_Rigid0001  -226.007998
0002_IP3_fullBinding_Rigid0002  -225.635657
0001_IP3_fullBinding_Rigid0001  -219.209742
0001_IP3_fullBinding_Rigid0002  -219.188106
0001_IP3_fullBinding_Rigid0003  -219.064542

我当前的脚本是:

#!/usr/bin/perl

use strict;
use warnings;

print "Name of all total energy containing file:\n";
my $energy_file = <STDIN>;
chomp $energy_file;

my $inputfile_energy = $energy_file;

open (INPUTFILE_ENERGY, "<", $inputfile_energy) or die $!;

print map $inputfile_energy->[0],
sort { $a->[1] <=> $b->[1] }
map { [ $_, /(\d+)$/ ] }
<INPUTFILE_ENERGY>;

close $inputfile_energy;

在这一点上,我只是想用他们的名字来获取能量,以正确的顺序打印。然后我将遍历目录中的文件,当名称与排序的能量名称匹配时,它将重新编号。

【问题讨论】:

  • 抱歉,仍然难以理解您要完成的工作。
  • 示例解决方案有帮助吗?
  • 没有连贯的打印是问题...不过我会记住这一点!

标签: arrays perl sorting file-handling


【解决方案1】:

你的脚本有问题:

  1. /(\d+)$/ 仅匹配行尾的数字 (0-9)。您的文件包含浮点数,因此仅匹配小数点后的数字。你可以用/(\S+)$/ 代替。 (实际上,在您的示例输入中有一行带有尾随空格,所以让我们改为 /(\S+)\s*$/

  2. $inputfile_energy 是一个文件名,一个标量,而不是一个引用,所以$inputfile_energy-&gt;[0] 没有意义。您将其用作map 构造中的表达式,而在map EXPR, LIST 构造中,$_ 指的是正在迭代的列表的当前元素,因此您可能只是想说$_-&gt;[0]

  3. 您的输入包含几行 - 全部使用关键字 Energy - 与您要排序的其他行的格式不同,应该被过滤掉。

综上所述,当倒数第二条语句如下所示时,我得到了工作代码:

print map $_->[0],
    sort { $a->[1] <=> $b->[1] }
    map { [ $_, /(\S+)\s*$/ ] }
    grep /\d/,
        <INPUTFILE_ENERGY>;

【讨论】:

    【解决方案2】:

    试试这个:

    print join "\n", sort {(split /\s+/,$a)[1] <=> (split /\s+/,$b)[1]} map{chomp $_; $_} <INPUTFILE_ENERGY>;
    

    【讨论】:

    • 作为仅代码的答案,我认为这确实会受益于更多的解释。
    【解决方案3】:

    你可以像这样使用 oneliner 并从命令行运行它:

    perl -lnae 'push @arr, [$_, $F[1]] if $F[1]; END { print join "\n", map {$_->[0]} sort {$a->[1] <=> $b->[1]} @arr }' energy_file.txt
    

    1) 特殊键 -n 使循环遍历输入文件 (energy_file.txt) 中的所有行;当前行在 $_ 变量中可用。

    2) 然后 key -a 用空格分割每一行并将非空值放入@F 数组中。

    【讨论】:

      【解决方案4】:

      一个不太“惯用”的解决方案可能是:

      @data = <DATA>;
      my @table;
      
      foreach(@data){
          chomp;
          next unless /^0/;     # skip Energy lines (or any other cleaning test)     
          @line = split /\s+/;
          push @table,[@line];  # build a 2d array
      }
      
      my @sortedTable = sort { $a->[1] <=> $b->[1] } @table;
      
      foreach(@sortedTable){
          printf(
              "%5s,%25s\n",
              $_->[0],
              $_->[1]
              ) # some pretty printing
      }
      
      
      __DATA__
                                        Energy
      0001_IP3_fullBinding_Rigid0001  -219.209742 
      0001_IP3_fullBinding_Rigid0002  -219.188106
      0001_IP3_fullBinding_Rigid0003  -219.064542
      0001_IP3_fullBinding_Rigid0004  -219.050730
      ....
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2021-01-16
        • 2013-05-19
        • 2014-05-07
        • 1970-01-01
        • 1970-01-01
        • 2010-10-19
        • 1970-01-01
        • 2014-05-19
        相关资源
        最近更新 更多