2016-04-24 70 views
3

我有下一個內容的文件:如何按日期排序文件的內容?

linux-4.4.1.tar.gz  31-Jan-2016 19:34 127M 
linux-4.4.2.tar.gz  17-Feb-2016 20:35 127M 
linux-4.4.3.tar.gz  25-Feb-2016 20:13 127M 
linux-4.4.4.tar.gz  03-Mar-2016 23:16 127M 
linux-4.4.5.tar.gz  09-Mar-2016 23:44 127M 
linux-4.4.6.tar.gz  16-Mar-2016 16:28 127M 
linux-4.4.7.tar.gz  12-Apr-2016 16:13 127M 
linux-4.4.8.tar.gz  20-Apr-2016 07:00 127M 
linux-4.4.tar.gz  10-Jan-2016 23:12 127M 
linux-4.5.1.tar.gz  12-Apr-2016 16:08 128M 
linux-4.5.2.tar.gz  20-Apr-2016 07:00 128M 
linux-4.5.tar.gz  14-Mar-2016 04:38 128M 

,我想獲得本內容由他們的日期過濾了,但是我不知道我怎麼能做到這一點,到目前爲止,我只是下面的代碼轉換日期的比較 - 但林不知道如何使用它在bash代碼,以過濾文件:

date -d 20-Apr-2016 +"%Y%m%d" 
+0

你看到這個http://stackoverflow.com/questions/3193720/unix-sorting-with-primary-and-secondary-keys –

+1

不知道你是如何生成的文件。如果它帶有'ls',那麼可以按日期排序 - 參見'man ls'。順便說一句。過濾可減少行數,排序排序。你的問題聽起來像是排序而不是過濾器... – jerik

回答

1

如果您習慣使用GNU AWK,那麼像這樣的腳本將工作:

conv _date.awk

BEGIN { # sort array numerically 
     PROCINFO["sorted_in"] = "@ind_num_asc" 
     # prepare a mapping month name to month-number: 
     split("JAN FEB MAR APR MAY JUN JUL AUG SEP OCT NOV DEC", tmp," ") 
     for(ind in tmp) { monthMap [ tmp[ ind ] ] = ind } 
     } 

     { split($2, dt, /[-]/) 
     ts = mktime(dt[3] " " monthMap[ toupper(dt[2]) ] " " dt[1] " 0 0 0") 
     if (ts in lines) lines[ts] = lines[ts] "\n" $0 
     else lines[ts] = $0 
     } 

END { # output in chronological order 
     for(l in lines) print lines[ l ] 
     } 

使用方法如下:awk -f conv_date.awk your_file

+0

當你有兩個文件具有相同的日期和時間戳時會發生什麼? –

+0

@jaypalsingh感謝您的提示,我添加了一個檢查該案件。 –

2

Schwartzian transform

while read -r line; do 
    d=$(date -d "${line:24:11}" +"%Y%m%d") 
    echo "$d $line" 
done < file | sort -k1,1n | cut -d " " -f 2- 

輸出:

 
linux-4.4.tar.gz  10-Jan-2016 23:12 127M 
linux-4.4.1.tar.gz  31-Jan-2016 19:34 127M 
linux-4.4.2.tar.gz  17-Feb-2016 20:35 127M 
linux-4.4.3.tar.gz  25-Feb-2016 20:13 127M 
linux-4.4.4.tar.gz  03-Mar-2016 23:16 127M 
linux-4.4.5.tar.gz  09-Mar-2016 23:44 127M 
linux-4.5.tar.gz  14-Mar-2016 04:38 128M 
linux-4.4.6.tar.gz  16-Mar-2016 16:28 127M 
linux-4.4.7.tar.gz  12-Apr-2016 16:13 127M 
linux-4.5.1.tar.gz  12-Apr-2016 16:08 128M 
linux-4.4.8.tar.gz  20-Apr-2016 07:00 127M 
linux-4.5.2.tar.gz  20-Apr-2016 07:00 128M 
+0

不錯的。但'24:11'的假設有點危險,是不是 – sjsam

+1

沒關係,爲了使它更健壯:'[[$ line =〜[^「」] *「」*([^「」] *)「 「[^」「] *」「[^」「] *]]; d = $(date -d「$ {BASH_REMATCH [1]}」+「%Y%m%d」)'。我假設他沒有使用標籤。 – Cyrus

0

保存腳本

#!/bin/bash 

reorder() 
{ 
awk '{printf "%s %s %s %s\n",$2,$3,$1,$4}' $1 \ 
| sort -t'-' -k2 -M \ 
| awk '{printf "%s %s %s %s\n",$3,$1,$2,$4}' #You can omit this pipe 
} 

reorder $1 

爲sortcontent.sh和像

./sortcontent.sh your_file_name 
2

運行它,如果開到perl然後使用Schwartzian變換最好是在它執行。這使用核心模塊,因此不需要從CPAN安裝一個模塊。

perl -MTime::Piece -lane' 
    push @rows, [ $_, join (" ", $F[1], $F[2]) ]; 
}{ 
    print for 
     map { $_->[0] } 
     sort { 
      Time::Piece->strptime($a->[1], "%d-%b-%Y %R") <=> 
      Time::Piece->strptime($b->[1], "%d-%b-%Y %R") 
     } 
     map { [ $_->[0], $_->[1] ] } @rows; 
' file 
linux-4.4.tar.gz  10-Jan-2016 23:12 127M 
linux-4.4.1.tar.gz  31-Jan-2016 19:34 127M 
linux-4.4.2.tar.gz  17-Feb-2016 20:35 127M 
linux-4.4.3.tar.gz  25-Feb-2016 20:13 127M 
linux-4.4.4.tar.gz  03-Mar-2016 23:16 127M 
linux-4.4.5.tar.gz  09-Mar-2016 23:44 127M 
linux-4.5.tar.gz  14-Mar-2016 04:38 128M 
linux-4.4.6.tar.gz  16-Mar-2016 16:28 127M 
linux-4.5.1.tar.gz  12-Apr-2016 16:08 128M 
linux-4.4.7.tar.gz  12-Apr-2016 16:13 127M 
linux-4.4.8.tar.gz  20-Apr-2016 07:00 127M 
linux-4.5.2.tar.gz  20-Apr-2016 07:00 128M