shaveax
shaveax

Reputation: 478

how can i sort the content of a file by date?

i have a file with the next content :

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

and i would like to get this content filtered by their dates , but im not sure how can i do that, so far i have only the following code to convert the dates for a comparation but im not sure how to use it in bash code in order to filter the file:

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

Upvotes: 3

Views: 714

Answers (4)

jaypal singh
jaypal singh

Reputation: 77135

If open to perl then Schwartzian transform is best implemented in it. This uses a core module so no need to install one from 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

Upvotes: 2

sjsam
sjsam

Reputation: 21965

Save the script

#!/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

as sortcontent.sh and run it like

./sortcontent.sh your_file_name

Upvotes: 0

Lars Fischer
Lars Fischer

Reputation: 10179

If you are comfortable using GNU AWK, then a script like this would work:

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 ]
      }

Use it like this: awk -f conv_date.awk your_file

Upvotes: 1

Cyrus
Cyrus

Reputation: 88756

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-

Output:

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

Upvotes: 2

Related Questions