2012-06-14 311 views
0

我有阵INPUTFILES n个文件排序阵列

INPUTFILES=(file_0 ... files_n-1) 

,我需要他们在排列顺序由第一行中的文件进行排序。

文件看起来像这样:

2012.09.20 17:10 
2012.11.21 00:10 
2012.12.22 15:10 
2012.12.23 15:10 

我已经函数比较两个文件:

IsSooner() { 
ONEFIRST=$(head -1 "${1}") 
ONELAST=$(tail -1 "${1}") 
TWOFIRST=$(head -1 "${2}") 
TWOLAST=$(tail -1 "${2}") 

TIMEFORMAT='Y.%m.%d %H:%M:' 

perl <<EOF 
use strict; 
use warnings; 

use Time::Piece; 

open STDERR, "> /dev/null"; 

my @dates1 = ("${ONEFIRST}","${ONELAST}"); 
my @range1 = map Time::Piece->strptime("\$_", "${TIMEFORMAT}"), @dates1; 

my @dates2 = ("${TWOFIRST}","${TWOLAST}"); 
my @range2 = map Time::Piece->strptime("\$_", "${TIMEFORMAT}"), @dates2; 

if (\$range1[0] < \$range2[0]) { 
    exit 0; 
} 

exit 1; 
EOF 

[ $? -eq 0 ] && { 
    return 0 
} 

return 1 
} 

早些时候将文件中的第一次约会,数组中的较小的指数都会有。

BASH中的解决方案,如果可取的话。

UPDATE 我不知道日期的格式。我只知道它将采用strftime(3c)格式。

+0

如果我明白,你想用shell替换perl吗? – tuxuday

+0

没有。 perl片段是必需的。我只需要重新排列INPUTFILES数组中的顺序。我只是添加比较函数,因为要设置集合的顺序,您必须具有可比项目。 – Rob

+0

你需要一个排序算法? – tuxuday

回答

3
  1. 在简单的循环读取每个文件的第一行,并保存该信息于散列,具有第一行的数据的散列键和文件名的散列值。

    my @inpufiles = ...; 
    my %hash; 
    foreach (@inputfiles) { 
        open(my $fh, $_) or die $!; 
        $hash{<$fh>} = $_; 
        close $fh; 
    } 
    
  2. 按键对散列进行排序并打印所有排序后的散列值。

    foreach (sort (keys(%hash))) { 
        print "$hash{$_}\n"; 
    } 
    

    如果您不想打印,只需将其存储回数组,然后做只是

    @inputfiles = map {$hash{$_}} sort (keys(%hash)); 
    

祝你好运!


[更新]

要按照你的问题的更新,我建议您可以存储值使用哈希:

$hash{Time::Piece->strptime(<$fh>, $timeformat)->epoch} = $_; 
+0

这是按词汇顺序排列的,正确的。如果是的话,这不会帮助我。那是因为我使用Time :: Piece对象来比较对方。 – Rob

+2

@Rob - 其他用户已经在您的问题下面写了评论,其中注意到**您不需要按照自定义排序对数据进行排序,因为您的数据位于“YYYY.MM .DD HH:NN“格式和”词法“排序是这种格式的正确解决方案... –

+0

只需将'$ hash {<$fh>} = $ _'更改为标准化值所需的任何值即可。我建议从时​​代开始正常化到秒。 –

0

你可以使用一个Schwartzian Transform排序列表文件:

my @inputfiles = 
    map { $_->[0] } 
    sort { $a->[1] cmp $b->[1] } 
    map { [ $_, do { open my($f), $_; chomp(my $time = <$f>); $time } ] } 
    qw/file_0 file_1 file_2/; 

T他实际上可以写成一个小bash管道,所以你甚至不需要perl:

INPUTFILES=($(grep -m1 '' file_0 file_1 file_2 | sort -t: -k2 | cut -d: -f1))