2012-06-14 278 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))