2014-02-15 66 views
0

我有,我將創建格式許多目錄「test_1.2.3_yyyymmdd」需要基於模式YYYYMMDD

例如路徑目錄排序test_1.2.3_20140214

一個常見的事情是,我將始終將日期(以yyyymmdd格式)作爲目錄名稱的一部分。理想情況下,文件 以不同的日期以相同的方式創建。

我在這裏的要求是基於目錄名稱的日期字段,我能夠實現與下面的命令

ls | sort -t_ -k3,3 

但是,當目錄獲取與創建有可能是時間對文件進行排序日期不是目錄名稱的最後一個字段。即使在這種情況下,我也希望 根據日期字符串對文件進行排序。有人可以告訴我如何做到這一點。

如果我能夠實現這種排序,那麼我必須刪除最舊的文件(基於yyyymmdd模式)。要求是路徑應該總是包含最新的10 目錄根據上面的排序,如果它是超過10,那麼我必須刪除最舊的目錄。

,因爲這不是基於-mtime

我想依靠UNIX工具/ Perl編程爲了這個,我不能find命令計數。

+0

您的文件名每個最多隻能包含一個連續8位數字的子字符串嗎? –

+0

嗨羅布,不會有文件名中的任何其他部分將有八個連續的數字。發生八位數字(日期yyyymmdd)將只有一次 – chidori

+0

*「...我必須刪除最老的文件(基於yyyymmdd模式)。」*如果兩個或多個文件具有相同的yyyymmdd會發生什麼? – Kenosis

回答

1

下面是要考慮的選項:

use strict; 
use warnings; 
use List::Util qw/min/; 

my %files; 

while (my $file = <DATA>) { 
    chomp $file; 
    my ($date) = $file =~ /([^_]+)$/; 
    push @{ $files{$date} }, $file; 
} 

local $, = "\n"; 
print @{ $files{ min keys %files } }; 

__DATA__ 
test_1.2.3_20140214 
test_A.B.C_20140214 
test_X.Y.Z_20140212 
test_1.2.3_20140210 
test_4.5.6_20140210 

輸出:

test_1.2.3_20140210 
test_4.5.6_20140210 

$VAR1 = { 
      '20140210' => [ 
          'test_1.2.3_20140210', 
          'test_4.5.6_20140210' 
         ], 
      '20140212' => [ 
          'test_X.Y.Z_20140212' 
         ], 
      '20140214' => [ 
          'test_1.2.3_20140214', 
          'test_A.B.C_20140214' 
         ] 
     }; 

使用split是首選,但你提到的日期字符串可能不是文件名的最後一部分。因此,你需要一些方法(split,正則表達式...)來獲取它。

在上面的腳本中,這些日期用作數組散列(HoA)中的鍵,並且這些值是對文件路徑列表的引用。 min from List::Util用於查找最小鍵值,因爲這將是最早的日期。

使用了HoA,以防有多個文件具有相同的yyyymmdd。

而不是print結果,將數組傳遞到unlink刪除文件,即unlink @{ $files{ min keys %files } };

散列的A Data::Dump顯示其結構。

希望這會有所幫助!

+0

感謝您的回覆,請嘗試使用您的建議。 我覺得最好的辦法是,檢查路徑中的目錄數是否大於10,如果是,然後根據可用的yyyymmdd對文件進行排序,然後執行'$ count = current_dir_count - 10',然後刪除它'ls | sort -t_ k3,3 |頭 - $ count | xargs rm -rf 但我唯一擔心的是,如果日期不是文件名的第三個字段會怎麼樣:( – chidori

+0

@chidori最受歡迎!你說,*「...如果日期不是第三個字段的文件名......「*這絕對是你需要解決的問題 – Kenosis

+1

@chidori - 如果日期字符串將* always *爲文件名中唯一的八位數字,你可以執行以下操作捕獲它:'我的($日期)= $文件=〜/(\ d {8})/;' – Kenosis