Assuming you have access to GNU tools (you do if you're running Linux), I would use stat
instead. For example:
$ ls -l
total 0
-rw-r--r-- 1 terdon terdon 0 Sep 15 16:49 file1
-rw-r--r-- 1 terdon terdon 0 Sep 15 16:39 file2
-rw-r--r-- 1 terdon terdon 0 Sep 15 16:29 file3
-rw-r--r-- 1 terdon terdon 0 Sep 15 16:19 file4
-rw-r--r-- 1 terdon terdon 0 Sep 15 16:09 file5
-rw-r--r-- 1 terdon terdon 0 Sep 15 15:59 file6
-rw-r--r-- 1 terdon terdon 0 Sep 15 15:49 file7
So, the 5th newest file is file5
. To print just that, you can do:
$ stat --printf '%Y %n\0' * | sort -zrnk1 |
awk -vRS='\0' 'NR==5{sub(/^[^ ]* /,"",$0); print}'
You could then easily make this into a shell function that can take N (5 in your example) as an argument. Just add these lines to your ~/.bashrc
or equivalent:
nthfile() {
stat --printf '%Y %n\0' * | sort -zrnk1 |
awk -vRS='\0' -vn="$1" 'NR==n{sub(/^[^ ]* /,"",$0); print}'
}
Note that this will also show you directories. If you need it to match hidden files as well run (assuming you're using bash) shopt -s dotglob
before the above command.
Explanation
stat --printf '%Y %n\0' *
: for each file or directory in the current folder, print the modification date in seconds since the epoch (%s
) and the file name (%n
) and end each line with \0
instead of \n
. This lets us deal correctly with file names containing newline characters.
sort -zrnk1
: sort the output in reverse sort order (-r
), from the newest to the eldest. The -z
tells sort
to expect null-terminated input lines. The -n
tells it to sort numerically and the -k1
to only consider the first field when sorting.
awk
:
-vRS='\0'
: set the input record (line) separator to \0
;
vn=$1
: set the variable n
to whatever was given as input to the function;
NR==n{}
: run this only on line n
(5 in the first example);
sub(/^[^ ]* /,"",$0); print
: substitute all non-space characters from the beginning of the line (^[^ ]*
) up to the 1st space and print the result