用perl对行进行排序

时间:2013-06-24 08:31:12

标签: regex perl sorting grep

我有一个看起来像的文件:

text text text text : 6 min
text text text text : 2 min
text text text text : 8 min
text text text text : 2 min

我需要对此文件进行排序以获得该输出:

text text text text : 2 min
text text text text : 2 min
text text text text : 6 min
text text text text : 8 min

我试图这样做,但它不起作用:

my @copy = ();
open (INFILE, $ARGV[0]);
while (<INFILE>) {
push (@copy, $_);
}
my @lines = sort grep /^: (\d+) min/ , @copy;
print @lines;

有没有简单的方法在perl中执行此操作?

6 个答案:

答案 0 :(得分:8)

sort

更容易
$ sort -t: -k2 file
text text text text : 2 min
text text text text : 2 min
text text text text : 6 min
text text text text : 8 min
  • -t:表示“将列的分隔符设置为:”
  • -k2表示“在第二列上过滤”,即在:之后。

答案 1 :(得分:4)

我可能会建议首先发布sort解决方案,因为它似乎最简单。这是一个perl版本。它基于Schwartzian transform。这不是必需的,但对于任何较大的文件,它可能是有效的,而且看起来有点整洁。

use strict;
use warnings;

my @lines = <>;    # read the input file
@lines = map $_->[1],
         sort { $a->[0] <=> $b->[0] }
         map { my ($num) = /:\s*(\d+)/; [ $num, $_ ] } @lines;
print @lines;

基本理念是:

  • map语句开头以提取数字,返回对包含该数字的双元素数组的引用,以及原始行[ $num, $_ ]
  • 根据第一个元素对结果列表进行排序。
  • 以另一个map语句结束,将我们的数组转换回原始行。

答案 2 :(得分:1)

你的正则表达式错了。你想要:

/[^:]+: (\d+) min/

另外,你不能这样做吗?

@copy = <INFILE>;

答案 3 :(得分:1)

如果必须是perl(fedorquis建议非常好),这个金块应该这样做:

my @file=<>;
foreach (sort {(split(' ',$a))[5] <=> (split(' ',$b))[5]} @file) {print;}

将文件名作为参数。

答案 4 :(得分:0)

您可以使用 Schwartzian变换根据数字

对数字进行排序
use strict;
use Data::Dumper;

my @lines = ("Test:2 min","Test:8 min","Test:6 min");
print Dumper(\@lines);

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

@lines = sort @lines;
print Dumper(\@lines);

输出:

$VAR1 = [
          'Test:2 min',
          'Test:8 min',
          'Test:6 min'
        ];
$VAR1 = [
          'Test:2 min',
          'Test:6 min',
          'Test:8 min'
        ];

答案 5 :(得分:0)

my @lines = map { $_->[1] } sort { $a->[0] <=> $b->[0]} map { [ /:\s(\d+)/, $_ ] } @copy

工作原理

从右边开始,第一个地图生成一个数组数组。每个数组元素包含从每一行中提取的数字作为第一个元素,整行作为第二个元素

接下来,排序适用于刚刚使用所谓的ufo运算符设置的数组的第一个元素进行数值比较

最后,最后一张地图仅提取第二个元素,现在顺序正确

此方法称为“Schwartzian变换”,位于perldoc perlfaq4部分“如何按(任何)排序数组?”